9

在维护COM接口时,是否应该以BSTRNULL? 换句话说,这两个函数调用是否应该产生相同的结果?

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

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

2 回答 2

14

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

Eric Lippert 在Eric 的 BSTR 语义完整指南中详细讨论了 BSTR :

让我先列出差异,然后详细讨论每一点。

  1. BSTR 对于 NULL 和 "" 必须具有相同的语义。PWSZ 通常具有不同的语义。

  2. 必须使用 SysAlloc* 系列函数分配和释放 BSTR。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 字符串。

于 2008-10-05T07:50:55.710 回答
5

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

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

于 2008-10-05T10:55:35.447 回答