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