我该如何显示这个VARIANT实例的值并将其保存在TStringList中?
COM VARIANT结构具有指向SAFEARRAY的指针数据成员parray和pparray,例如:
VARIANT V;
LPSAFEARRAY sa = V_ISBYREF(&V) ? V_ARRAYREF(&V) : V_ARRAY(&V);
另一方面,VCL Variant
类有一个已定义的 LPSAFEARRAY
转换运算符,因此您可以直接赋值(但仅当 Variant.VType
字段没有存在 varByRef
标志时),例如:
Variant V;
LPSAFEARRAY sa = V;
无论哪种方式,一旦您获得了
SAFEARRAY
指针,就可以使用SafeArray API访问
BSTR
值,例如:
bool __fastcall VariantToStrings(const Variant &V, TStrings *List)
{
if (!V_ISARRAY(&V)) return false;
LPSAFEARRAY sa = V_ISBYREF(&V) ? V_ARRAYREF(&V) : V_ARRAY(&V);
VARTYPE vt;
if (FAILED(SafeArrayGetVartype(sa, &vt))) return false;
if (vt != VT_BSTR) return false;
if (SafeArrayGetDim(sa) != 1) return false;
LONG lBound = -1, uBound = -1;
if (FAILED(SafeArrayGetLBound(sa, 0, &lBound))) return false;
if (FAILED(SafeArrayGetUBound(sa, 0, &uBound))) return false;
if ((lBound > -1) && (uBound > -1))
{
BSTR *values = NULL;
if (FAILED(SafeArrayAccessData(sa, (void**)&values))) return false;
try
{
List->BeginUpdate();
try
{
for (LONG idx = lBound; l <= uBound; ++idx)
{
String s;
if (values[idx] != NULL)
s = String(values[idx], SysStringLen(values[idx]));
List->Add(s);
}
}
__finally
{
List->EndUpdate();
}
}
__finally
{
SafeArrayUnaccessData(sa);
}
}
return true;
}
VarClear(V);
TVarData(V).VType = varOleStr;
您完全不需要这些。VCL Variant
类会初始化为一个空状态,因此没有必要赋值 VType
,因为您随后会立即将整个 Variant
赋予新值。
V = ComFunction->GetValues(); //<<<<----- V 为空
如果 V 是空的,那么 GetValues()
首先返回的就是一个空的 Variant
。
mystr = (wchar_t *)(TVarData(V).VString);
TVarData::VString
是一个 AnsiString&
引用,而不是 wchar_t*
指针。要将 VCL Variant
(而不是 COM VARIANT
)转换为 String
,只需按原样赋值,让 RTL 自动处理细节即可:
String mystr = V;