更简洁优雅的 VARIANT 类型使用方式
Posted
技术标签:
【中文标题】更简洁优雅的 VARIANT 类型使用方式【英文标题】:more concise and elegant way of using VARIANT type 【发布时间】:2013-10-11 19:27:15 【问题描述】:以下代码来自 MSDN 源代码示例,我有一个问题。
为什么我们需要使用多个VARIANT result;
定义来定义不同的变量?我们能否以更短的方式初始化不同类型(主要是整数和字符串)的VARIANT
变量?简洁安全的方法。
另外,可以将VariantInit(&result)
替换为result.vt = VT_EMPTY
以将VARIANT
标记为空吗?
int main()
//blahblahbla
VARIANT x;
x.vt = VT_R4; // 4-byte real.
x.fltVal = 1.2f;
wprintf(L"Set FloatProperty = %.2f\n", x.fltVal);
hr = AutoWrap(DISPATCH_PROPERTYPUT, NULL, pSimpleObj, L"FloatProperty", 1, x);
VARIANT result;
VariantInit(&result);
hr = AutoWrap(DISPATCH_PROPERTYGET, &result, pSimpleObj, L"FloatProperty", 0);
wprintf(L"Get FloatProperty = %.2f\n", result.fltVal);
VARIANT result;
VariantInit(&result);
hr = AutoWrap(DISPATCH_METHOD, &result, pSimpleObj, L"HelloWorld", 0);
wprintf(L"Call HelloWorld => %s\n", result.bstrVal);
VariantClear(&result);
【问题讨论】:
【参考方案1】:为什么我们需要使用不同的“VARIANT result”变量?
您不必这样做,这只是示例的编写方式。重用 VARIANT 变量时要小心,仅调用 VariantInit() 或分配 result.vt = VT_EMPTY 是危险的。变体可以存储需要释放的资源。正如在 sn-p 中所做的那样,请注意释放 BSTR 所需的对 VariantClear() 的调用。与 VariantInit() 不同的是,VariantClear 在再次初始化变体之前首先释放资源。
还要注意在 DISPATCH_PROPERTYGET 调用之后它是如何被省略的。没关系,但你必须知道你在做什么。在这种情况下可以,因为 VARIANT 可以存储浮点值而无需为其分配内存。无论如何调用 VariantClear() 肯定没有错。
请记住,MSDN 源代码通常是用 C 编译器编写的。如果您编写 COM 代码,那么您几乎总是倾向于使用 C++。哪位肯定能做得更好,现在可以使用_variant_t class。一个包装类,可以避免愚蠢的错误并使语法更清晰,正如您所要求的。您不再需要使用 VariantInit 或 VariantClear,包装器会为您完成它并且永远不会出错。
【讨论】:
【参考方案2】:直接使用VARIANT
的替代方法是使用C++ 可用的包装类之一。根据您是使用 MFC 还是 ATL 还是仅使用本机 C++,有多种选择。
对于一个简单的包装器,_variant_t
类提供了一些基本便利,尤其是对于简单数据,例如整数和字符串。该类不直接支持SAFEARRAY
类型VARIANTS
。
请参阅Microsoft Developer Network topic _variant_t Class,它提供了包装类和可用方法的概述。
_variant_t
对象封装了VARIANT
数据类型。班上 管理资源分配和释放并进行函数调用 酌情发送至VariantInit
和VariantClear
。
构造函数有多种变体,它们采用不同的参数类型并创建适当类型的VARIANT
对象。对于标准的 Windows API UNICODE 或 wchar_t
字符串,您需要使用 BSTR
对象。
ATL 提供CComVariant
,MFC 提供COleVariant
类来包装VARIANT
。这三个包装类(_variant_t
、CComVariant
和 COleVariant
似乎都派生自 struct tagVARIANT
,VARIANT
的底层数据结构,因此所有这些似乎都可用于任何使用 @ 的接口987654343@.
来自Microsoft Developer Network CComVariant Class的CComVariant
的注释
CComVariant 包装了 VARIANT 和 VARIANTARG 类型,它由一个 union 和一个成员,指示存储在 联盟。 VARIANT 通常用于自动化。
CComVariant 派生自 VARIANT 类型,因此可以在任何地方使用它 可以使用变体。例如,您可以使用 V_VT 宏 提取 CComVariant 的类型,或者您可以访问 vt 成员 就像使用 VARIANT 一样。
还有来自Microsoft Developer Network COleVariant Class 的COleVariant
的注释:
该类派生自 VARIANT 结构。这意味着您可以 在调用 VARIANT 的参数中传递 COleVariant 并且 VARIANT 结构的数据成员是可访问的数据成员 的 COleVariant。
【讨论】:
以上是关于更简洁优雅的 VARIANT 类型使用方式的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot - 使用Assert校验让业务代码更简洁