如何直接访问C ++中的VARIANT变量?

问题描述 投票:-2回答:1

我的程序使用一个外部ocx库并通过它接收数据。下面的代码显示了它的工作方式。

    VARIANT    varArrItem, varArrData;

    ocx_instance.GetItemArr(real, &varArrItem);      // the library provides GetItemArr
                                                     // 1) receives data 
    long lLBound, lUBound;
    VARIANT varItem, varData;

    long index[2];
    index[0] = 0;
    index[1] = 0;

    COleSafeArray* pSafeItemArr = (COleSafeArray*)&varArrItem;    // 2) casts varArrItem to COleSafeArray
    CString strItem;
    CStringArray arrItem;

    pSafeItemArr->GetLBound(1, &lLBound);
    pSafeItemArr->GetUBound(1, &lUBound);

    int nItemCnt = (lUBound - lLBound + 1);
    for (int i = 0; i < nItemCnt; i++)
    {
        index[0] = i;
        VariantInit(&varItem);

        pSafeItemArr->GetElement(index, (void *)&varItem);    // 3) gets its values using GetElement
        strItem = varItem.bstrVal;
        arrItem.Add(strItem);

        VariantClear(&varItem);
    }

该程序的一个大问题是,只要有新数据到达,该代码就会运行,这种情况经常发生,并且会消耗大量资源。因此,我想简化代码,仅获取varArrItem的内容,例如字符串或字符串结构数组。

varArrItem.vt给我8204,据说它由8192(VT_ARRAY)12(VT_VARIANT)组成。我被困在这里,之后不知道该怎么办。我怎样才能简单地获取其中的内容?是否可以在不使用COleSafeArray的情况下访问它们?

c++ windows variant
1个回答
0
投票

您不需要使用COleSafeArray,它只是为了方便起见而包装。您可以直接从SAFEARRAY*中提取varArrItem指针,然后直接使用SafeArray API:SafeArrayGet(L|U)Bound()SafeArrayGetElement()等,尽管如果性能很重要,请考虑使用SafeArrayAccessData()访问VARIANT[]数组直接,因此是其BSTR指针。复制数据的次数越少,代码运行速度就越快。此代码实际需要制作的唯一数据副本是varArrItemstrItem

的赋值
VARIANT varArray;
ocx_instance.GetItemArr(real, &varArray);

LPSAFEARRAY psa = varArrar.parray;

LONG lLBound, lUBound;
SafeArrayGetLBound(psa, 1, &lLBound);
SafeArrayGetUBound(psa, 1, &lUBound); 

CStringArray arrItem;

VARIANT *varArrayData;
SafeArrayAccessData(psa, (void**) &varArrayData);

int nItemCnt = (lUBound - lLBound + 1);
for (int i = 0; i < nItemCnt; i++) {
    CString strItem = varArrayData[i].bstrVal;
    arrItem.Add(strItem);
}

SafeArrayUnaccessData(psa);
© www.soinside.com 2019 - 2024. All rights reserved.