【问题标题】:When using W2A to convert BSTR to std::string, is there any clean up needed?使用 W2A 将 BSTR 转换为 std::string 时,是否需要进行任何清理?
【发布时间】:2026-01-27 05:15:02
【问题描述】:

代码如下所示:

class A 
{
  public:
     std::string name;
};

A a;
CComBSTR textValue;
// some function which fills textValue
a.name = W2A(textValue);

现在,我使用了 CComBSTR,因此我不必释放 BString,但是 W2A 是否分配了我可能必须处理的任何内存?即我应该有:

 char *tmp = W2A(textValue);
 a.name = tmp;
 // do something to deallocate tmp?

【问题讨论】:

    标签: c++ com bstr


    【解决方案1】:

    对 W2A/A2W 宏要非常谨慎。它们是用“alloca”(直接在堆栈上动态分配)实现的。在某些涉及循环/递归/长字符串的情况下,您会得到一个“*”(不开玩笑)。

    推荐的方法是使用“新”帮助程序模板。见ATL and MFC String Conversion Macros

    A a;
    CComBSTR textValue;
    // some function which fills textValue
    CW2A pszValue( textValue );
    a.name = pszValue;
    

    转换使用 128 字节的常规“堆栈中”缓冲区。如果它太小,则自动使用堆。您可以直接使用模板类型来调整权衡

    A a;
    CComBSTR textValue;
    // some function which fills textValue
    CW2AEX<32> pszValue( textValue );
    a.name = pszValue;
    

    别担心:你只是减少了堆栈的使用,但如果 32 字节不够用,就会使用堆。正如我所说,这是一种权衡。如果您不介意,请使用CW2A

    无论哪种情况,都不需要清理:-)

    请注意,当 pszValue 超出范围时,任何待转换的 char* 都可能指向垃圾。请务必阅读“示例 3 错误使用转换宏”。和上面链接中的“关于临时类实例的警告”。

    【讨论】:

    • 对“新”助手的提及非常棒。我一直希望找到一些不会超出我的堆栈的东西,就是这样。谢谢你,谢谢你,谢谢你! +1!
    • @MPW 谢谢。别客气。不要忘记:UNICODE 的代码一路向下,很多问题都会消失... :-)
    【解决方案2】:

    不需要清理,因为W2A allocates memory on the stack。您必须注意某些与内存相关的陷阱(堆栈分配的直接后果),但在这种特定情况下,没有什么会立即引起怀疑。

    【讨论】:

      最近更新 更多