为什么使用 CComBSTR 而不是只传递 WCHAR*?
我是 COM 新手。 的优点到底是什么?
L"String"
Replace: with
CComBSTR(L"String")
我可以在 .NET 应用程序的 COM 部分看到一个更改列表,其中所有字符串都以这种方式替换。想知道这个有什么必要。
I'm new to COM. What exactly is the advantage of replacing:
L"String"
with
CComBSTR(L"String")
I can see a changelist in the COM part of my .NET application where all strings are replaced in this way. Would like to know what is the need for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
BSTR
与WCHAR[]
不同。BSTR
值以其长度为前缀,并且以 null 结尾。如果您正在处理用 C 或 C++ 编写的进程内对象,您通常会摆脱这种情况,因为 C/C++ 代码可能会假设您的 BSTR 是一个以 null 结尾的宽字符串。
另一方面,如果您正在处理进程外/跨机器对象,则代理/存根编组代码将假设您确实传递了 BSTR,并且期望找到一个长度字段(它需要这是为了知道要整理多少数据)。这会出错。
简而言之:如果需要 BSTR,请调用 SysAllocString(或 CComBSTR、或 CString::AllocSysString)。
BSTR
is not the same asWCHAR[]
.BSTR
values are prefixed with their length, as well as null-terminated.If you're dealing with in-process objects that are written in C or C++, you'll usually get away with this, because the C/C++ code will probably assume that your BSTR is a null-terminated wide character string.
If, on the other hand, you're dealing with out-of-process/cross-machine objects, the proxy/stub marshalling code will assume that you really did pass a BSTR, and will expect to find a length field (it needs this to know how much data to marshal). This will go horribly wrong.
In short: if something expects a BSTR, call SysAllocString (or CComBSTR, or CString::AllocSysString).
您可以将 L"Something" 传递到声明为需要 BSTR 的 COM 方法中,但绝对不应该这样做。
约定是使用 SysAllocString() 系列函数之一分配 BSTR,任何收到 BSTR 的人都可以(并且应该)在想要查找字符串长度时调用 SysStringLen()。 SysStringLen() 依赖于使用 SysAllocString() 系列函数分配的 BSTR(因为它使用由这些函数分配和初始化的额外数据),如果违反该要求,程序将遇到未定义的行为。
直接使用 SysAllocString() 还需要调用 SysFreeString() 来释放字符串(否则内存会泄漏),因此会导致大量代码并可能导致错误。更好的方法是使用 CComBSTR 或 _bstr_t 等包装类来管理 BSTR - 它们会在必要时调用 SysAllocString()/SysFreeString()(当然,除非您滥用它们)。
You could just pass L"Something" into a COM method declared as expecting a BSTR but you should never do so.
The convention is that a BSTR is allocated using one of SysAllocString() family functions and anyone who receives a BSTR can (and should) call SysStringLen() whenever they want to find the string length. SysStringLen() relies on the BSTR being allocated with SysAllocString() family functions (since it uses extra data allocated and initialized by those functions) and if that requirement is violated the program will run into undefined behaviour.
Using SysAllocString() directly requires also calling SysFreeString() to free the string (otherwise memory is leaked) so it leads to lots of code and possibly to errors. The better way is just using a wrapper class such as CComBSTR or _bstr_t for managing the BSTRs - they will call SysAllocString()/SysFreeString() when necessary (unless you abuse them, of course).