描述:
在COM中,除了IUnknown的AddRef,Release(返回ULONG参数)特殊外,其它的任何函数都必须返回HRESULT.
所以就有了传入参数,传出参数.
如果传入传出的仅仅是基本类型的数据,如int,long,BYTE等,那也没有资源释放问题(由本地栈解决了).
如果传入传出的是一些Pointer,如BSTR,IDispatch&等那就存在一个资源释放的问题,可是它们该由那一方释放啊,还是双方都要释放.就像编译器指令__stdcall一样,规定了参数栈该由那一方恢复.
下面举一个例子:
A组件:
idl片段:
HRESULT Hello([out]BSTR* bstrOut);
实现:
HRESULT Hello(BSTR* bstrOut){
*bstrOut=SysAllocString(OLESTR("Hello"));
//需要释放该BSTR资源吗? 还是由调用者释放?
//SysFreeString(*bstrOut);
return S_OK;
}
B组件:
idl片段:
HRESULT Goodbye([in]BSTR bstrIn);
实现:
HRESULT Goodbye(BSTR bstrIn){
....
//该方法调用者在方法返回时是否也要释放该资源?
SysFreeString(bstrIn);
return S_OK;
}
请教各位大侠........
解决方案1:
对于in参数,自然是客户分配,组件也不用释放
对于out参数,组件用任务分配器分配,客户也要用任务分配器释放
任务分配器是一个专门用于管理由组件分配的内存需要客户释放的问题,它是一个实现了IMalloc接口的组件。COM提供一个已有的实现。具体用法是:
组件内使用CoTaskMemAlloc,然后在客户端使用CoTaskMemFree(如果客户端是VB,运行时解释器自动调用)
如果要重新分配[in, out]参数的内存大小,组件内不要使用CoTaskMemAlloc而应使用CoTaskMemRealloc
对于BSTR类型,有专用的函数SysAllocString和SysFreeString
[in],[in,out],[out]的顶级指针由client负责分配和回收(除非out string,由组件分配,客户回收,分别使用CoTaskMemAlloc,CoTaskMemFree),关于次级指针较复杂(com本质论有详细论述),也很少会用(即结构体中的指针成员).
解决方案3: 对于[in]参数没什么好说的。
对于[out]参数,COM里面有个约定,由COM分配内存,由调用者来释放。