本文主要是介绍CComBSTR 内存结构一瞥,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一直迷惑于以下函数调用:
// 被调用函数
STDMETHODIMP CAppt::GetAttendees(LPBSTR lpbstrXML){}// 调用函数段
CComBSTR bstrXML;
HRESULT hr = (*m_ppSettingsSink)->GetAttendees(&bstrXML);
为什么一个 CComBSTR 变量取地址之后能对应一个 LPBSTR 指针?
查阅了很多资料,最貌似能合理解释的一个说法是从 CComBSTR 内存结构角度阐述(如下图, from atlcomcli.h)
class CComBSTR
{
public:BSTR m_str;CComBSTR() throw(){m_str = NULL;}
...
}
大概意思就是说,因为 CComBSTR
类型可以隐式转换为 BSTR
,因为有相应的运算符重载。而 LPBSTR
实际上是 BSTR*
类型,即指向 BSTR
类型的指针。所以在函数被调用时,参数会发生隐式的类型转换。
CComBSTR ccomBstr(L"Hello, COM!");
BSTR bstr = ccomBstr; // 隐式转换调用 operator BSTR 运算符,将 CComBSTR 转换为 BSTR
在上述示例中,将 CComBSTR
对象 ccomBstr
赋值给 BSTR
类型的变量 bstr
时,编译器会自动调用 CComBSTR
类的 operator BSTR
运算符重载,将 ccomBstr
转换为 BSTR
类型的指针。
结合 LPBSTR 和 BSTR 的定义(如下图)
typedef wchar_t* BSTR;
typedef BSTR *LPBSTR;
但仔细揣摩,还是解释不了最初的疑惑。直到调试程序后一眼就看明白了原委。
答案解释起来简单至极,就是因为在物理地址上 &ccomBstrXml.m_str 其实等同于 &ccomBstrXml。
不太严谨的一个等式: &ccomBstrXml == &ccomBstrXml.m_str == LPBSTR
这篇关于CComBSTR 内存结构一瞥的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!