【问题标题】:more concise and elegant way of using VARIANT type更简洁优雅的 VARIANT 类型使用方式
【发布时间】: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);
    }
}

【问题讨论】:

    标签: visual-c++ variant


    【解决方案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 数据类型。班上 管理资源分配和释放并进行函数调用 酌情发送至VariantInitVariantClear

      构造函数有多种变体,它们采用不同的参数类型并创建适当类型的VARIANT 对象。对于标准的 Windows API UNICODE 或 wchar_t 字符串,您需要使用 BSTR 对象。

      ATL 提供CComVariant,MFC 提供COleVariant 类来包装VARIANT。这三个包装类(_variant_tCComVariantCOleVariant 似乎都派生自 struct tagVARIANTVARIANT 的底层数据结构,因此所有这些似乎都可用于任何使用 @ 的接口987654343@.

      来自Microsoft Developer Network CComVariant ClassCComVariant的注释

      CComVariant 包装了 VARIANT 和 VARIANTARG 类型,它由一个 union 和一个成员,指示存储在 联盟。 VARIANT 通常用于自动化。

      CComVariant 派生自 VARIANT 类型,因此可以在任何地方使用它 可以使用变体。例如,您可以使用 V_VT 宏 提取 CComVariant 的类型,或者您可以访问 vt 成员 就像使用 VARIANT 一样。

      还有来自Microsoft Developer Network COleVariant ClassCOleVariant 的注释:

      该类派生自 VARIANT 结构。这意味着您可以 在调用 VARIANT 的参数中传递 COleVariant 并且 VARIANT 结构的数据成员是可访问的数据成员 的 COleVariant。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 2012-07-30
        • 1970-01-01
        • 2015-05-19
        • 2023-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多