如何最好地将 CString 转换为 BSTR 以将其作为“in”传递参数传入 COM 方法?
我需要将 CString
实例转换为正确分配的 BSTR
并将该 BSTR
传递到 COM 方法中。为了使代码能够针对 ANSI 和 Unicode 进行相同的编译和工作,我使用 CString::AllocSysString() 来将任何格式的 CString 转换为 Unicode BSTR。
由于没有人拥有返回的 BSTR,因此我需要处理它并在调用完成后以尽可能最安全的方式释放它并使用尽可能少的代码。
目前,我使用 ATL::CComBSTR 进行生命周期管理:
ATL::CComBSTR converted;
converted.Attach( sourceString.AllocSysString() ); //simply attaches to BSTR, doesn't reallocate it
interface->CallMethod( converted );
我不喜欢的是,我需要两个单独的语句来构造绑定到的 ATL::CComBSTR
转换结果。
有更好的方法来完成同样的任务吗?
I need to convert a CString
instance into a properly allocated BSTR
and pass that BSTR
into a COM method. To have code that compiles and works indentically for both ANSI and Unicode I use CString::AllocSysString()
to convert whatever format CString
to a Unicode BSTR.
Since noone owns the returned BSTR I need to take care of it and release it after the call is done in the most exception-safe manner posible and with as little code as possible.
Currently I use ATL::CComBSTR
for lifetime management:
ATL::CComBSTR converted;
converted.Attach( sourceString.AllocSysString() ); //simply attaches to BSTR, doesn't reallocate it
interface->CallMethod( converted );
what I don't like here is that I need two separate statements to just construct the ATL::CComBSTR
bound to the convertion result.
Is there a better way to accomplish the same task?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
CComBSTR
具有char*
和wchar_t*
的重载构造函数,它们会调用您的SysAllocString()
代表。因此,代码片段中的显式分配实际上是不必要的。以下内容也同样有效:此外,如果您不需要在代码中的其他位置使用转换后的
BSTR
,则可以在方法调用中就地执行对象构造,如下所示:这同样适用于
_bstr_t
类,如果您不希望依赖于 ATL,则可以使用该类来代替CComBSTR
。CComBSTR
has overloaded constructors for bothchar*
andwchar_t*
, which make the call toSysAllocString()
on your behalf. So the explicit allocation in your code snippet is actually unnecessary. The following would work just as well:Furthermore, if you have no need to use the converted
BSTR
elsewhere in your code, you can perform the object construction in-place in the method call, like so:The same applies to the
_bstr_t
class, which can be used instead ofCComBSTR
if you don't want a dependency on the ATL.Windows 编程中令人困惑的方面之一是管理 Visual Basic 样式字符串与 C 语言样式字符串之间的转换。并不是说有多难,只是很难记住细节。通常不经常这样做,而且 MSDN 文档非常庞大,很难找到问题的答案。但是,最糟糕的部分是,您可以执行一些编译良好的类型转换,但无法按您期望的方式工作。这会导致代码无法工作,并且错误很难追踪。经过一些经验后,您将学会确保字符串转换符合您的预期。
C 字符串是以 NULL 字符结尾的字符数组。 Visual Basic 字符串的不同之处在于字符串的长度位于字符串中的字符之前。因此,VB 字符串知道自己的长度。此外,所有 VB 字符串都是 Unicode(每个字符 16 位)。
字符串类型
BSTR/C 字符串转换是必需的,如果:
One of the confusing aspects of Windows programming is managing the conversion of Visual Basic style strings to/from C language style strings. It isn't that it is so difficult, it is just difficult to remember the details. It is usually not done often, and the MSDN documentation is so voluminous that it is difficult to find answers to your questions. But, the worst part is that you could perform some typecast that compiles fine, but doesn't work the way you expect. This results in code that doesn't work, and the bugs are hard to track down. After some experience, you learn to make sure your string conversions are doing what you expect.
C strings are arrays of characters terminated by a NULL character. Visual Basic strings differ in that the length of the string precede the characters in the string. So, a VB string knows its own length. In addition, all VB strings are Unicode (16 bits per character).
String Types
BSTR/C String conversions are required if:
_bstr_t
构造函数之一允许您简单地附加到现有BSTR
,以便您可以在CString::AllocSysString
时获得您想要的异常code>BSTR 分配失败。_bstr_t
构造函数文档说:另一方面,
CComBSTR
构造函数好像没有相应的签名;尽管如果实际上不需要BSTR
分配失败异常,也可以使用它,正如 Phil Booth 在他的回答中。One of
_bstr_t
constructors allows you to simply attach to existingBSTR
so that you can have the exception that you want fromCString::AllocSysString
whenBSTR
allocation fails.The
_bstr_t
constructor documentation says:On the other hand,
CComBSTR
constructor doesn't seem to have the corresponding signature; although it can be used as well ifBSTR
allocation failure exception is not really needed, as mentioned by Phil Booth in his answer.