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>