描述:
1.首先允许我描述一下使用_bstr_t,BSTR的场景.
IDL片段:
interface IWorld: IUnknown{
HRESULT GetBSTR([out]BSTR* pXml);
}
实现片段:
STDMETHODIMP CWorld::GetBSTR(BSTR* pXml){
// 该_bstr_t的构造器会SysAllocString一个OLESTR("<xml>..</xml>"的
// BSTR,然后Encapsulated这个BSTR.
_bstr xml(
OLESTR("<xml><Message>Hello World</Message></xml>"),
false);
//现在返回一个BSTR.典型的如下返回
*pXml=xml.copy();
return S_OK;
}
2. 现在仔细思考上面的代码,我觉得用 *pXml=xml.copy()返回一个BSTR实在是太浪了.
分析如下:
当_bstr_t进行构造时,它先SysAllocString,也就是说我的字符串已经在COM
的内存管理器中分配了.
当用 *pXml=xml.copy()返回时,根据MSDN原文对_bstr_t的copy函数的描述:
Microsoft Specific
BSTR copy( ) const throw(_com_error);
Remarks
Returns a newly allocated copy of the encapsulated BSTR object.
也就是说,它又重新分配了一次BSTR.
哦,如果我的字符串足够大的惊人,那这种返回方式真是效率太低了.
3.改进
在改进过程中,我发现一个很矛盾的事.
为了减少不必要的重新分配内存.我把原始的_bstr_t(已经包含了BSTR)直接返回.
也就是把 *pXml=xml.copy() 改为 *pXml=(BSTR)xml
矛盾就在此:
xml变量是一个_bstr_t类,当它离开自己的作用域时,编译器会自动地加上它的析构
函数 ~_bstr_t.
~_bstr_t的实现中肯定得SysFreeString它所包含的BSTR.
但是我把它包含的BSTR已经返回了.
也就是说我返回了一个SysFreeString的BSTR.......
但是程序调试时竟然是正确的????????????????
各位大侠,这为啥????????????
感谢参与...........