我需要将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
。
有没有更好的方法来完成相同的任务?
CComBSTR
为char*
和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在他的回答中提到的那样。