空BSTR和NULL BSTR之间应该有区别吗?

时间:2008-10-05 07:45:02

标签: com string bstr

维护COM界面时,空BSTR的处理方式应与NULL相同吗? 换句话说,这两个函数调用应该产生相同的结果吗?

 // Empty BSTR
 CComBSTR empty(L""); // Or SysAllocString(L"")
 someObj->Foo(empty);

 // NULL BSTR
 someObj->Foo(NULL);     

2 个答案:

答案 0 :(得分:14)

是 - NULL BSTR与空BSTR相同。我记得当我们从VS6切换到2003时,我们遇到了各种各样的错误 - CComBSTR类改变了使用NULL而不是空字符串分配它的默认构造函数。例如,当您将BSTR视为常规C样式字符串并将其传递给某个函数(如strlen)或尝试使用它初始化std::string时,会发生这种情况。

Eric Lippert在Eric's Complete Guide To BSTR Semantics中详细讨论了BSTR:

  

让我先列出差异   然后讨论每一点   令人难以忍受的细节。

     

1)BSTR必须相同   NULL和“”的语义。一个PWSZ   经常有不同的语义   那些。

     

2)必须分配和释放BSTR   与SysAlloc *系列的   功能。 PWSZ可以是   来自的自动存储缓冲区   堆栈或分配malloc,new,   LocalAlloc或任何其他内存   分配器。

     

3)BSTR具有固定长度。一个PWSZ   可以是任何长度,仅受限于   其中的有效内存量   缓冲液中。

     

4)BSTR始终指向第一个   缓冲区中的有效字符。一个PWSZ   可能是指向中间或结尾的指针   字符串缓冲区。

     

5)当你分配一个n字节的BSTR时   有n / 2宽字符的空间。   为PWSZ分配n个字节时   你可以存储n / 2 - 1个字符 -   你必须留出空间。

     

6)BSTR可以包含任何Unicode数据   包括零字符。一个PWSZ   从不包含零字符   除了作为字符串结束标记。   BSTR和PWSZ都有   最后一次有效后的零字符   字符,但在BSTR中有效   字符可能是零字符。

     

7)BSTR实际上可能包含奇数   字节数 - 可用于   移动二进制数据。 PWSZ是   几乎总是偶数个字节   并仅用于存储Unicode   字符串。

答案 1 :(得分:4)

处理这种困境的最简单方法是使用CComBSTR并检查.Length()为零。这适用于空值和NULL值。

但是,请记住,必须释放空的BSTR或存在内存泄漏。我最近在其他代码中看到了一些。如果你不仔细看,很难找到。