Com 组合赋值

Com 组合赋值,com,com-interop,atl,bstr,Com,Com Interop,Atl,Bstr,我对COM字符串分配感到困惑。以下哪个字符串赋值是正确的。为什么? CComBSTR str; . . Obj->str = L"" //Option1 还是应该如此 Obj->str = CComBSTR(L"") //Option2 原因是什么就我个人而言,我更喜欢选项1,因为它不需要构造新的CComBSTR对象。(当然,他们的代码在幕后是否这样做是另一回事。)我个人更喜欢选项1,因为这不需要构造新的CComBSTR对象。(当然,他们的代码在幕后是否这样做是另一回事。)如

我对COM字符串分配感到困惑。以下哪个字符串赋值是正确的。为什么?

CComBSTR str;
.
.
Obj->str = L""  //Option1
还是应该如此

Obj->str = CComBSTR(L"")  //Option2

原因是什么

就我个人而言,我更喜欢选项1,因为它不需要构造新的
CComBSTR
对象。(当然,他们的代码在幕后是否这样做是另一回事。)

我个人更喜欢选项1,因为这不需要构造新的
CComBSTR
对象。(当然,他们的代码在幕后是否这样做是另一回事。)

如果使用
str=CComBSTR(L“”)
则使用:

如果使用
str=L”“
则使用:


它们都将正确初始化CComBSTR对象。

如果使用
str=CComBSTR(L“”)
则使用:

如果使用
str=L”“
则使用:


它们都将正确初始化CComBSTR对象。

首选选项1,因为它只为字符串分配一次,而选项2则为字符串分配一次(尽管没有特殊原因创建了新的临时对象)。与VC++中的bstr_t类型不同,ATL one不执行引用的计数字符串,因此它将复制整个字符串

首选选项1,因为它只对字符串执行一次分配,而选项2执行一次分配(尽管没有特殊原因创建了新的临时对象)。与VC++中的bstr_t类型不同,ATL one不执行引用的计数字符串,因此它将复制整个字符串

实际的
BSTR
是:

  • 从COM堆临时分配(通过
    SysAllocString()
    和系列)
  • 一种数据结构,其中字符串数据前面有其长度,存储在32位值中
  • 作为指向该数据结构第五个字节的指针传递,字符串数据位于该字节
请参阅文档:

大多数接受BSTR的函数在通过BSTR创建简单赋值时不会崩溃。这导致了混淆,因为人们观察到似乎正在工作的代码,从中推断
BSTR
可以像任何
WCHAR*
一样初始化。这个推论是错误的

只有real
BSTR
可以传递给OLE自动化接口

通过使用调用
SysAllocString()
CComBSTR()
构造函数,您的代码将创建一个真正的
BSTR
CComBSTR()
析构函数将负责通过
SysFreeString()
将分配的存储返回给系统


如果将
CComBSTR()
传递给拥有所有权的API,请确保调用
.Detach()
方法以确保未释放
BSTR
BSTR
不进行引用计数(与COM对象不同,COM对象不进行引用计数),因此多次尝试释放
BSTR
将崩溃。

真实的
BSTR
是:

  • 从COM堆临时分配(通过
    SysAllocString()
    和系列)
  • 一种数据结构,其中字符串数据前面有其长度,存储在32位值中
  • 作为指向该数据结构第五个字节的指针传递,字符串数据位于该字节
请参阅文档:

大多数接受BSTR的函数在通过BSTR创建简单赋值时不会崩溃。这导致了混淆,因为人们观察到似乎正在工作的代码,从中推断
BSTR
可以像任何
WCHAR*
一样初始化。这个推论是错误的

只有real
BSTR
可以传递给OLE自动化接口

通过使用调用
SysAllocString()
CComBSTR()
构造函数,您的代码将创建一个真正的
BSTR
CComBSTR()
析构函数将负责通过
SysFreeString()
将分配的存储返回给系统

如果将
CComBSTR()
传递给拥有所有权的API,请确保调用
.Detach()
方法以确保未释放
BSTR
BSTR
未对引用计数(与COM对象不同,COM对象是计数的),因此多次尝试释放
BSTR
将崩溃

CComBSTR( LPCSTR pSrc );
CComBSTR& operator =(LPCSTR pSrc);