从书籍《ATL Internals》中,我了解到BSTR与OLECHAR*不同,并且有CComBSTR和CString可用于BSTR。
根据MSDN的为BSTR分配和释放内存,我知道调用者/被调用者需要负责内存管理。
以MSDN上的这行代码为例:
我想尽快将BSTR转换为CString/CComBSTR。对于转换来说,值语义和引用语义是完全不同的情况。我已经深入研究了CComBSTR.Attach、CComBSTR.AssignBSTR等函数,但这些代码都不能解决我的困惑。
MSDN上的CComBSTR.Attach代码片段让我感觉不对,因为它没有遵循为BSTR分配和释放内存的规定。《ATL Internals》中提到,如果使用SetSysString,它将“释放传入的原始BSTR”,这将违反BSTR参数约定,就像CComBSTR.Attach一样。
总之,我想在实现中使用CString来处理原始的BSTR,但不知道正确的方法。我已经在我的项目中编写了一些代码,虽然能够正常工作,但我仍然感到紧张,因为我不知道自己是否正确。
根据MSDN的为BSTR分配和释放内存,我知道调用者/被调用者需要负责内存管理。
以MSDN上的这行代码为例:
HRESULT CMyWebBrowser::put_StatusText(BSTR bstr)
我仍然不知道如何在我的实现中正确处理bstr。由于我对BSTR仍有一个基本问题——在COM接口边界上,我们应该将bstr视为值(例如int)还是引用(例如int *)。我想尽快将BSTR转换为CString/CComBSTR。对于转换来说,值语义和引用语义是完全不同的情况。我已经深入研究了CComBSTR.Attach、CComBSTR.AssignBSTR等函数,但这些代码都不能解决我的困惑。
MSDN上的CComBSTR.Attach代码片段让我感觉不对,因为它没有遵循为BSTR分配和释放内存的规定。《ATL Internals》中提到,如果使用SetSysString,它将“释放传入的原始BSTR”,这将违反BSTR参数约定,就像CComBSTR.Attach一样。
总之,我想在实现中使用CString来处理原始的BSTR,但不知道正确的方法。我已经在我的项目中编写了一些代码,虽然能够正常工作,但我仍然感到紧张,因为我不知道自己是否正确。
HRESULT CMyWebBrowser::put_StatusText(BSTR bstr)
{
// What I do NOT know
CString str1; // 1. copy bstr (with embeded NUL)
CString str2; // 2. ref bstr
// What I know
CComBSTR cbstr1;
cbstr1.AssignBSTR(bstr); // 3. copy bstr
CComBSTR cbstr2;
cbstr2.Attach(bstr); // 4. ref bstr, do not copy
// What I do NOT know
// Should we copy or ref bstr ???
}
BSTR
,否则通过指针传递BSTR*
。如果你有嵌入的NUL
,你可以将它复制到std::wstring
中,而不是CString
。 - Mr.C64BSTR
看作是使用特殊 COM 分配器分配的const wchar_t*
,并且带有长度前缀(因此它可以嵌入NUL
)。 - Mr.C64