_bstr_t与BSTR的矛盾?

wuthering 2004-04-02 10:22:44
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.......
但是程序调试时竟然是正确的????????????????

各位大侠,这为啥????????????
感谢参与...........






...全文
118 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuthering 2004-04-02
  • 打赏
  • 举报
回复
我用_bstr_t,主要是考虑到它冲载了 + 运算符
对于连接字符串的操作是比较方便的.
如果用BSTR,那我就又回到了API的石器时代.得频繁地调用wcscat,还要注意各种字符类型wchar_t,
BSTR,char*等之间的转换.
一不小心忘了SysFreeString,就造就一个Memory Leak
LeeZi 2004-04-02
  • 打赏
  • 举报
回复
STDMETHODIMP CWorld::GetBSTR(BSTR* pXml)
{
*pXml=::SysAllocString(L"<xml><Message>Hello World</Message></xml>");
return S_OK;
}
xenke 2004-04-02
  • 打赏
  • 举报
回复
其实_bstr_t并没有你说的那么差劲,在你这种情况下应该调用xml.Detach(),如果你在不同的进程中使用这个函数,调试会出错!
天限天空 2004-04-02
  • 打赏
  • 举报
回复
Detach

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧