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

Com 空BSTR和空BSTR之间应该有区别吗?,com,string,bstr,Com,String,Bstr,维护COM接口时,空的BSTR是否应与NULL一样处理? 换句话说,这两个函数调用是否应该产生相同的结果 // Empty BSTR CComBSTR empty(L""); // Or SysAllocString(L"") someObj->Foo(empty); // NULL BSTR someObj->Foo(NULL); 是-空BSTR与空BSTR相同。我记得当我们从VS6切换到2003年时,发现了各种各样的bug——CComBSTR类更改了默认构

维护
COM
接口时,空的
BSTR
是否应与
NULL
一样处理? 换句话说,这两个函数调用是否应该产生相同的结果

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

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

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

Eric Lippert详细讨论了BSTR:

让我先列出它们之间的区别 然后讨论本节中的每一点 令人痛苦的细节

  • BSTR必须具有相同的 NULL和“”的语义。PWSZ 通常对于 那些

  • 必须分配并释放BSTR 使用SysAlloc*系列 功能。PWSZ可以是 来自服务器的自动存储缓冲区 堆叠或分配malloc,新, LocalAlloc或任何其他内存 分配器

  • BSTR具有固定长度。PWSZ 可以是任何长度,仅限于 内存中的有效内存量 缓冲区

  • BSTR总是指向第一个 缓冲区中的有效字符。PWSZ 可以是指向中间或末端的指针 字符串缓冲区的名称

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

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

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


  • 处理这个难题的最简单方法是使用CComBSTR并检查.Length()是否为零。这适用于空值和空值


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

    我遇到过MSXML代码不遵守NULL==empty规则,并且表现出两者不同的行为。但那是5年前的事了(如果我没记错的话,是MSXML 3),希望他们现在已经解决了这个问题。:-。NET互操作也不遵守规则-它们将“”封送到String.Empty,将NULL封送到NULL。从技术上讲,它们是不同的。由实现决定是否将null作为空字符串处理。看见