在维护COM接口时,空的BSTR
是否应与NULL
处理方式相同?换句话说,这两个函数调用是否会产生相同的结果?
// Empty BSTR
CComBSTR empty(L""); // Or SysAllocString(L"")
someObj->Foo(empty);
// NULL BSTR
someObj->Foo(NULL);
strlen
),或者尝试用它初始化一个std::string
时。首先列出不同之处,然后逐点详细讨论每个问题。
BSTR在NULL和""的语义上必须完全相同,而PWSZ在这些方面通常具有不同的语义。
BSTR必须使用SysAlloc*函数族进行分配和释放。PWSZ可以是来自堆栈的自动存储缓冲区或使用malloc、new、LocalAlloc或任何其他内存分配器进行分配。
BSTR长度固定,而PWSZ可以是任意长度,仅受其缓冲区中有效内存量的限制。
BSTR始终指向缓冲区中的第一个有效字符,而PWSZ可能是指向字符串缓冲区中间或末尾的指针。
当为n字节BSTR分配空间时,你可以存储n/2个宽字符。当你为PWSZ分配n字节时,你可以存储n/2-1个字符 - 你必须留出空间来放置null。
BSTR可以包含任何Unicode数据,包括零字符。而PWSZ除了作为字符串结束标记外,永远不会包含零字符。BSTR和PWSZ都有一个固定的长度,由其缓冲区中的字符数确定。
在C字符串中,最后一个有效字符后必须为零;但在BSTR中,有效的字符可以是零字符。
BSTR实际上可能包含奇数个字节--它可以用于移动二进制数据。PWSZ几乎总是偶数个字节,并且仅用于存储Unicode字符串。
处理这个问题的最简单方法是使用CComBSTR并检查.Length()是否为零。这适用于空值和NULL值。
但是,请记住,必须释放空BSTR,否则将会有内存泄漏。最近我在别人的代码中发现了一些这样的问题。如果您没有仔细寻找,那么这些问题很难发现。