windows 如何最好地将 CString 转换为 BSTR 以将其作为“in”参数传递给 COM 方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2086493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to best convert CString to BSTR to pass it as an "in" parameter into a COM method?
提问by sharptooth
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.
我需要将CString
实例转换为正确分配的实例并将其BSTR
传递BSTR
给 COM 方法。为了让代码同时为 ANSI 和 Unicode 编译和工作,我使用CString::AllocSysString()
将任何格式转换CString
为 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.
由于没有人拥有返回的 BSTR,我需要处理它并在调用完成后以最异常安全的方式和尽可能少的代码释放它。
Currently I use ATL::CComBSTR
for lifetime management:
目前我ATL::CComBSTR
用于终身管理:
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.
我不喜欢这里的是我需要两个单独的语句来构造ATL::CComBSTR
转换结果的绑定。
Is there a better way to accomplish the same task?
有没有更好的方法来完成同样的任务?
回答by Phil Booth
CComBSTR
has overloaded constructors for both char*
and wchar_t*
, which make the call to SysAllocString()
on your behalf. So the explicit allocation in your code snippet is actually unnecessary. The following would work just as well:
CComBSTR
已重载两个构造char*
和wchar_t*
,这使得调用SysAllocString()
代表您。因此,您的代码片段中的显式分配实际上是不必要的。以下内容也同样有效:
ATL::CComBSTR converted = sourceString;
interface->CallMethod(converted);
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:
此外,如果您不需要BSTR
在代码的其他地方使用转换后的对象,您可以在方法调用中就地执行对象构造,如下所示:
interface->CallMethod(ATL::CComBSTR(sourceString));
The same applies to the _bstr_t
class, which can be used instead of CComBSTR
if you don't want a dependency on the ATL.
这同样适用于_bstr_t
类,CComBSTR
如果您不想依赖 ATL ,则可以使用它。
回答by Ramesh Alavala
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.
Windows 编程的一个令人困惑的方面是管理 Visual Basic 样式字符串与 C 语言样式字符串之间的转换。不是很难,只是细节很难记住。通常不会经常这样做,而且 MSDN 文档非常庞大,以至于很难找到问题的答案。但是,最糟糕的部分是您可以执行一些编译良好的类型转换,但不能按您期望的方式工作。这会导致代码不起作用,并且很难追踪错误。经过一些经验后,您将学会确保您的字符串转换符合您的预期。
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
C 字符串是由 NULL 字符终止的字符数组。Visual Basic 字符串的不同之处在于字符串的长度在字符串中的字符之前。因此,VB 字符串知道它自己的长度。此外,所有 VB 字符串都是 Unicode(每个字符 16 位)。字符串类型
BSTR/C String conversions are required if:
在以下情况下需要 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.
回答by Afriza N. Arief
One of _bstr_t
constructors allows you to simply attach to existing BSTR
so that you can have the exception that you want from CString::AllocSysString
when BSTR
allocation fails.
其中一个_bstr_t
构造函数,您只需连接到现有的BSTR
,这样你可以有你想从异常CString::AllocSysString
时BSTR
分配失败。
// _bstr_t simply attaches to BSTR, doesn't reallocate it
interface->CallMethod( _bstr_t(sourceString.AllocSysString(), false) );
The _bstr_t
constructor documentationsays:
该_bstr_t
构造的文件说:
_bstr_t(
BSTR bstr,
bool fCopy
);
fCopy
If false, thebstr
argument is attached to the new object without making a copy by callingSysAllocString
.
fCopy
如果为 false,则bstr
通过调用将参数附加到新对象而不进行复制SysAllocString
。
On the other hand, CComBSTR
constructordoesn't seem to have the corresponding signature; although it can be used as well if BSTR
allocation failure exception is not really needed, as mentioned by Phil Boothin his answer.
另一方面,CComBSTR
构造函数似乎没有相应的签名;尽管如果BSTR
真的不需要分配失败异常,它也可以使用,正如Phil Booth在他的回答中提到的。