关于什么时候使用CoTaskMemAlloc/CoTaskMemFree来申请/释放内存

转 http://blog.csdn.net/gaoxiaowei/article/details/5701789


从网上看来的说法:
The thing is that COM (actually the RPC runtime library, but it's easier to blame COM) has an additional requirement for [out] pointers.  This requirement is that if the type of an [out] parameter isn't a scalar quantity (in other words if it's a structure or anything more complicated than a int or float), then the memory pointed to by the [out] parameter needs to be allocated either by MIDL_user_allocate (for RPC) orCoTaskMemAlloc(for COM).

也就是说,如果需要调用COM接口,并且接口中有[out]的参数,且类型不是整形或浮点数之类的基本数据类型,就需要调用CoTaskMemAlloc来申请这块内存,并使用完毕后调用CoTaskMemFree来释放。
以下是一个使用 C 语言封装 GetIDsOfNames 和 Close 方法的示例,用于关闭 Excel 应用程序: ```c #include <stdio.h> #include <windows.h> // 定义 IDispatch 接口 typedef struct IDispatch IDispatch; struct IDispatchVtbl { HRESULT (__stdcall* QueryInterface)(IDispatch*, const IID*, void**); ULONG (__stdcall* AddRef)(IDispatch*); ULONG (__stdcall* Release)(IDispatch*); HRESULT (__stdcall* GetTypeInfoCount)(IDispatch*, UINT*); HRESULT (__stdcall* GetTypeInfo)(IDispatch*, UINT, LCID, ITypeInfo**); HRESULT (__stdcall* GetIDsOfNames)(IDispatch*, const IID*, LPOLESTR*, UINT, LCID, DISPID*); HRESULT (__stdcall* Invoke)(IDispatch*, DISPID, const IID*, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*); }; struct IDispatch { struct IDispatchVtbl* lpVtbl; }; // 声明 Excel 应用程序类 typedef struct { IDispatch* pApplication; } ExcelApplication; // 获取 Excel 应用程序 IDispatch 接口 HRESULT GetExcelApplication(ExcelApplication* pExcel) { CLSID clsid; HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid); if (FAILED(hr)) { return hr; } IUnknown* pUnknown; hr = CoCreateInstance(&clsid, NULL, CLSCTX_LOCAL_SERVER, &IID_IUnknown, (void**)&pUnknown); if (FAILED(hr)) { return hr; } hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, (void**)&pExcel->pApplication); pUnknown->lpVtbl->Release(pUnknown); return hr; } // 调用 Excel 方法 HRESULT InvokeExcelMethod(ExcelApplication* pExcel, const char* methodName) { // 转换方法名为 LPOLESTR 类型 int n = strlen(methodName); LPOLESTR szMethodName = (LPOLESTR)CoTaskMemAlloc(sizeof(OLECHAR) * (n + 1)); if (szMethodName == NULL) { return E_OUTOFMEMORY; } mbstowcs(szMethodName, methodName, n + 1); // 获取方法 ID DISPID dispid; HRESULT hr = pExcel->pApplication->lpVtbl->GetIDsOfNames(pExcel->pApplication, &IID_NULL, &szMethodName, 1, LOCALE_USER_DEFAULT, &dispid); CoTaskMemFree(szMethodName); if (FAILED(hr)) { return hr; } // 调用方法 VARIANT result; EXCEPINFO excepInfo; DISPPARAMS dispParams = {0}; hr = pExcel->pApplication->lpVtbl->Invoke(pExcel->pApplication, dispid, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispParams, &result, &excepInfo, NULL); if (SUCCEEDED(hr)) { VariantClear(&result); } return hr; } // 关闭 Excel 应用程序 HRESULT CloseExcel(ExcelApplication* pExcel) { // 调用 Quit 方法 HRESULT hr = InvokeExcelMethod(pExcel, "Quit"); if (FAILED(hr)) { return hr; } // 释放 IDispatch 接口 pExcel->pApplication->lpVtbl->Release(pExcel->pApplication); return S_OK; } int main() { // 获取 Excel 应用程序 IDispatch 接口 ExcelApplication excel; HRESULT hr = GetExcelApplication(&excel); if (FAILED(hr)) { printf("Failed to get Excel application: %08X\n", hr); return 1; } // 关闭 Excel 应用程序 hr = CloseExcel(&excel); if (FAILED(hr)) { printf("Failed to close Excel: %08X\n", hr); return 1; } return 0; } ``` 在上面的代码中,我们定义了 ExcelApplication 类来封装 Excel 应用程序的 IDispatch 接口,并使用 GetExcelApplication 方法来获取该接口。然后,我们使用 InvokeExcelMethod 方法来调用 Excel 的 Quit 方法,最后使用 CloseExcel 方法来关闭 Excel 应用程序,并释放 IDispatch 接口资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值