我看杨老师的COM 组件设计与应用(五),里面的例子COM组件的Cat方法:
STDMETHODIMP CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
{
// TODO: Add your implementation code here
         int nLen1 = ::SysStringLen( s1 ); // s1 的字符长度
int nLen2 = ::SysStringLen( s2 ); // s2 的字符长度
    
*pVal = ::SysAllocStringLen( s1, nLen1 + nLen2 );// 构造新的 BSTR 同时把 s1 先保存进去
if( nLen2 )
{
::memcpy( *pVal + nLen1, s2, nLen2 * sizeof(WCHAR) ); // 然后把 s2 再连接进去
}

return S_OK;
}
而在客户端调用时,
BSTR s1= ::SysAllocString(L"Hello");
BSTR s2= ::SysAllocString(L" World!");
BSTR s3=NULL;
hr=pIFun->Cat(s1,s2,&s3);
if(FAILED(hr))
{
cout<<"函数调用失败Cat"<<endl;
return;
}
最后是:
// IFun::Cat()最后一个参数是 [out] 方向属性,因此调用者要释放内存
if( s3 )  ::SysFreeString( s3 );
}我想问:此时SysFreeString(s3)释放的是组件中构造的pVal吗?
如果是,我觉得奇怪,SysFreeString是在客户端运行的,应该是释放客户端的内存变量,
如果有类似于pIFun->这样的,才有可能释放组件中内存变量,这该如何解释?
如果是释放客户端中的变量,可是客户端的内存变量s3并没用SysAllocString()初始化,请问
这该怎么理解?
另外:如果说是释放组件中内存变量,那有什么办法来验证下吗?

解决方案 »

  1.   

    首先弄清楚一点,COM组件可以运行在本机上,也可以运行在远程机器上(DCOM)。
    操作系统内部实现了COM内存管理机制。
    如果你的COM对象是本机的,你调用SysFreeString(s3)会通过COM内存管理机制释放本机的内存。如果是COM对象运行在远程机器上,它除了要释放本地的内存,还要通知远程计算机释放相应的内存。
      

  2.   

    调用SysFreeString(s3)会通过COM内存管理机制释放本机的内存?
    ===================================================
    怎么通知COM内存管理机制释放本机的内存?
      

  3.   

    COM内部实现会有这个内存管理,释放s3的时候内部就会进行这些释放
      

  4.   

    这些内存既不是客户端分配的,也不是服务器分配的,而是在COM堆上分配的,所以不能用malloc/new之类的分配,必须使用API,因此不存在跨模块释放内存的问题。