c++ 调用com的形式
c++ 调用com的方式
一、在需要的文件中引入com对应的dll文件
#import "xuhh_math.dll" no_namespace, named_guids, auto_search
在调用的地方
HRESULT hr = ::CoInitialize(NULL); if ( hr == S_OK ) { CComPtr<IXuhh_Math> math; hr = math.CoCreateInstance(CLSID_Xuhh_Math); if ( hr == S_OK ) { math.dosomething(); } } math.Release();//释放资源 math=NULL; CoUninitialize();
二、引入xuhh_math.dll产生的*.h,*_i.c文件,利用CoCreateInstance函数来调用
演示代码:
/*在工程中加入*_i.c文件,例如本例的xuhh_math_i.c,该文件定义了类和接口的guid值,如果不引入的话,会发生连接错误。*
#include "xuhh_math_i.h" CoInitialize(NULL); IXuhh_Math* math= NULL; HRESULT hr = CoCreateInstance(CLSID_Xuhh_Math, NULL, CLSCTX_ALL, IID_IXuhh_Math, (void**)&math); if (SUCCEEDED(hr) && (math != NULL)) { math->dosomething(); } CoUninitialize();
三、不用CoCreateInstance,直接用CoGetClassObejct得到类厂对象接口,然后用该接口的方法CreateInstance来生成实例。
演示代码:
/*前期准备如二方法所述*/
<span style="font-size:18px;"> IClassFactory* pcf = NULL;
HRESULT hr = CoGetClassObject(CLSID_Xuhh_Math, CLSCTX_ALL, NULL, IID_IClassFactory,(void**)&pcf);
if (SUCCEEDED(hr) && (pcf != NULL))
{
IXuhh_Math* math = NULL;
hr = pcf->CreateInstance(NULL, IID_IXuhh_Math, (void**)&math);
if (SUCCEEDED(hr) && (math!= NULL))
{
math->dosomething();
}
pcf->Release();
}</span>
四、
在MFC中除了上面的几种方法外,还有一种更方便的方法,就是通过ClassWizard利用类型库生成包装类,不过有个前提就是com组件的接口必须是派生自IDispatch
具体方法:
1、按Ctrl+W调出类向导,按Add Class按钮弹出新菜单,选From a type libarary,然后定位到xuhh_math.dll,接下来会出来该中的所有接口,向导会自动生成相应的.cpp和.h文件.
这样你就可以在你的MFC工程中像使用普通类那样使用COM组件了.
演示代码:
<span style="font-size:18px;"> CoInitialize(NULL); CXuhh_Math math; if (m_FirstClass.CreateDispatch(_T("xuhhCOM.xuhh_math.1")) != 0) { math->dosomething(); } CoUninitialize();</span>
如果有连接点事件的话,需要些一个接收器下面附录一个接收器类:
<strong><span style="font-size:18px;">class IRecv : public IDispatch { long m_nRet; public: IRecv() { m_nRet = 1 ; } ~IRecv() { } virtual HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid, /* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) { *ppvObject = this; this->AddRef(); return S_OK ; } virtual ULONG STDMETHODCALLTYPE AddRef( void) { InterlockedIncrement(&m_nRet); return m_nRet; } virtual ULONG STDMETHODCALLTYPE Release( void) { InterlockedDecrement(&m_nRet); return m_nRet; } virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount( /* [out] */ __RPC__out UINT *pctinfo) { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( /* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) { return E_NOTIMPL; } virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( /* [in] */ __RPC__in REFIID riid, /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames, /* [range][in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId) { return E_NOTIMPL; } virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( /* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS *pDispParams, /* [out] */ VARIANT *pVarResult, /* [out] */ EXCEPINFO *pExcepInfo, /* [out] */ UINT *puArgErr) { switch (dispIdMember) { case 1: LONG ret = *(pDispParams->rgvarg->plVal) ; printf("%d\r\n",ret); } return S_OK ; } };</span></strong>