如何最好地将CString转换为BSTR将其作为“in”parameter passing给COM方法?

我需要将CString实例转换为正确分配的BSTR ,并将该BSTR传递给COM方法。 要使编译和ANSI和Unicode统一工作的代码我使用CString::AllocSysString()将任何格式的CString转换为Unicode BSTR。

由于没有人拥有返回的BSTR,所以我需要照顾它,并在调用完成之后以最安全的方式进行释放,并尽可能使用尽可能less的代码。

目前我使用ATL::CComBSTR进行终身pipe理:

  ATL::CComBSTR converted; converted.Attach( sourceString.AllocSysString() ); //simply attaches to BSTR, doesn't reallocate it interface->CallMethod( converted ); 

我不喜欢这里是我需要两个单独的语句只是构造绑定到转换结果的ATL::CComBSTR

有没有更好的方法来完成相同的任务?

CComBSTRchar*wchar_t*重载了构造函数,它们SysAllocString()您的名义对SysAllocString()进行调用。 所以你的代码片段中的显式分配实际上是不必要的。 以下内容也可以发挥作用:

 ATL::CComBSTR converted = sourceString; interface->CallMethod(converted); 

此外,如果您不需要在代码的其他地方使用转换后的BSTR ,则可以在方法调用中就地执行对象构造,如下所示:

 interface->CallMethod(ATL::CComBSTR(sourceString)); 

这同样适用于_bstr_t类,如果你不想要依赖于ATL的话,可以用它来代替CComBSTR

Windows编程令人困惑的一个方面是管理Visual Basic风格字符串到C语言风格字符串的转换。 这并不是那么困难,只是难以记住细节。 通常不会经常这样做,而且MSDN文档太庞大,很难找到您的问题的答案。 但是,最糟糕的是你可以执行一些编译好的类型转换,但是不能按照你期望的方式工作。 这导致代码无法正常工作,而且这些错误很难追踪到。 经过一些经验之后,您将学习如何确保您的字符串转换符合您的期望。

C字符串是由NULL字符终止的字符数组。 Visual Basic字符串的不同之处在于字符串的长度在字符串中的字符之前。 所以,VB字符串知道它自己的长度。 另外,所有VB字符串都是Unicode(每个字符16位)。 字符串类型

BSTR / C字符串转换是必需的,如果:

 You are doing COM programming in C/C++ You are writing multiple language applications, such as C++ DLL's accessed by Visual Basic applications. 

其中一个_bstr_t构造函数允许您简单地附加到现有的BSTR以便在BSTR分配失败时可以从CString::AllocSysString的异常。

 // _bstr_t simply attaches to BSTR, doesn't reallocate it interface->CallMethod( _bstr_t(sourceString.AllocSysString(), false) ); 

_bstr_t构造函数文档说:

 _bstr_t( BSTR bstr, bool fCopy ); 

fCopy
如果为false,则bstr参数将附加到新对象,而不通过调用SysAllocString进行复制。

另一方面, CComBSTR构造函数似乎没有相应的签名; 尽管如果没有真正需要BSTR分配失败例外,也可以使用它,正如Phil Booth在他的回答中提到的那样。