为啥要使用 CComBSTR 而不是只传递 WCHAR*?
Posted
技术标签:
【中文标题】为啥要使用 CComBSTR 而不是只传递 WCHAR*?【英文标题】:Why use CComBSTR instead of just passing a WCHAR*?为什么要使用 CComBSTR 而不是只传递 WCHAR*? 【发布时间】:2010-12-17 03:13:45 【问题描述】:我是 COM 新手。替换到底有什么好处:
L"String"
与
CComBSTR(L"String")
我可以在我的 .NET 应用程序的 COM 部分中看到一个更改列表,其中所有字符串都以这种方式替换。想知道这个有什么需求。
【问题讨论】:
【参考方案1】:BSTR
与 WCHAR[]
不同。 BSTR
值以它们的长度为前缀,并且以 null 结尾。
如果您正在处理用 C 或 C++ 编写的进程内对象,您通常会侥幸成功,因为 C/C++ 代码可能会假定您的 BSTR 是一个以空字符结尾的宽字符串.
另一方面,如果您正在处理进程外/跨机器对象,则代理/存根编组代码将假定您确实通过了 BSTR,并期望找到一个长度字段(它需要这个来知道要编组多少数据)。这会大错特错。
简而言之:如果需要 BSTR,请调用 SysAllocString(或 CComBSTR,或 CString::AllocSysString)。
【讨论】:
【参考方案2】:您可以将 L"Something" 传递给声明为期望 BSTR 的 COM 方法,但您永远不应该这样做。
约定是使用 SysAllocString() 系列函数之一分配 BSTR,并且接收 BSTR 的任何人都可以(并且应该)在想要查找字符串长度时调用 SysStringLen()。 SysStringLen() 依赖于通过 SysAllocString() 系列函数分配的 BSTR(因为它使用由这些函数分配和初始化的额外数据),如果违反该要求,程序将运行未定义的行为。
直接使用 SysAllocString() 还需要调用 SysFreeString() 来释放字符串(否则内存泄漏),因此会导致大量代码并可能导致错误。更好的方法是使用诸如 CComBSTR 或 _bstr_t 之类的包装类来管理 BSTR——它们会在必要时调用 SysAllocString()/SysFreeString()(当然,除非你滥用它们)。
【讨论】:
以上是关于为啥要使用 CComBSTR 而不是只传递 WCHAR*?的主要内容,如果未能解决你的问题,请参考以下文章
C:为啥你可以通过值传递(给函数)一个结构,而不是一个数组?