{public:CmyInterface();virtual~CmyInterface();//我们必须要为QueryInterface编写代码STDMETHOD(QueryInterface)(REFIIDriid,LPVOID*ppv);//ImyInterface接口方法STDMETHOD(Square)(long*pVal);STDMETHOD(Cube)(long*pVal); 厦门金蝶
};
模版类InterfaceImpl<>提供接口引用计数的实现。在此我们可以用多接口继承,那样就能在一个COM组件中实现多个接口。
ikuaiji.com 爱会计网
examv.com
爱德财税
维时财税
格仕咨询 kdkis.cn
第三步:在完成这个对象之前,我们还要编写Queryinterface和两个接口方法:
STDMETHODIMPCmyInterface::QueryInterface(REFIIDriid,LPVOID*ppv){*ppv=NULL;if(IsEqualIID(riid,IID_IUnknown)||IsEqualIID(riid,__uuidof(ImyInterface))){//因为我们从ImyInterface继承,所以要进行强制类型转换*ppv=(ImyInterface*)this;_AddRef();//这个方法从某个基类继承而来returnS_OK;}returnE_NOINTERFACE;}STDMETHODIMPCmyInterface::Square(long*pVal){longvalue=*pVal;*pVal=value*value;returnS_OK;}STDMETHODIMPCmyInterface::Cube(long*pVal){longvalue=*pVal;*pVal=value*value*value;returnS_OK;} 注意这里使用了__uuidof(ImyInterface)来获取接口的IID,这是因为我们已经在第一步中将这个接口关联到了某个uuid。
最后一步:COM组件的DLLs必须输出一个叫DllGetClassObject的函数。由这个函数为CmyInterface创建类工厂并返回一个
对它的引用。然后我们调用CoCreateInstance为进程内COM创建类工厂,接着调用DllGetClassObject。这个类工厂有一个方
法是CreateInstance,由这个方法创建对象并返回对它的引用。
STDAPIDllGetClassObject(REFCLSIDrclsid,REFIIDriid,LPVOID*ppvOut){*ppvOut=NULL;if(IsEqualIID(rclsid,CLSID_Mine)){//为CmyInterface类声明类工厂CClassFactory*pcf=newCClassFactory;returnpcf->QueryInterface(riid,ppvOut);}returnCLASS_E_CLASSNOTAVAILABLE;} 在此我们要检查所请求的CLSID是不是CLSID_Mine,如果不是则返回一个错误代码。 你可能会问在哪里创建实际的CmyInterface类对象,实际上这是由CClassFactory的模板实例来处理的。以下是CClassFatory的实现:
//CSingleCreator用于单实例类工厂,这个类为多个CreateObject请求返回相同的对象指针..templateclassCSingleCreator{protected:CSingleCreator():m_pObj(0){};comObj*CreateObject(){if(!m_pObj){m_pObj=newcomObj;}returnm_pObj; pqie.com }comObj*m_pObj;};//CMultiCreator用于常用类工厂,这个类为每一个CreateObject请求返回新的对象指针..templateclassCMultiCreator{protected:CMultiCreator():m_pObj(0){};comObj*CreateObject(){returnnewcomObj;}comObj*m_pObj;};//ClassFactory类实现//MultiCreator是缺省的类工厂创建者//这个类实现了接口IclasFactory......classCClassFactory:publicCComBase<>,publicInterfaceImpl,publiccreatorClass{public:CClassFactory(){};virtual~CClassFactory(){};STDMETHOD(QueryInterface)(REFIIDriid,LPVOID*ppv){*ppv=NULL;if(IsEqualIID(riid,IID_IUnknown)||IsEqualIID(riid,IID_IClassFactory)){*ppv=(IClassFactory*)this;_AddRef();returnS_OK;}returnE_NOINTERFACE;}STDMETHODIMPCreateInstance(LPUNKNOWNpUnkOuter,REFIIDriid,LPVOID*ppvObj){*ppvObj=NULL;if(pUnkOuter)returnCLASS_E_NOAGGREGATION;m_pObj=CreateObject();//m_pObj在creatorClass中定义 优纳财税 if(!m_pObj)returnE_OUTOFMEMORY;HRESULThr=m_pObj->QueryInterface(riid,ppvObj);if(hr!=S_OK){deletem_pObj;}returnhr;}STDMETHODIMPLockServer(BOOL){returnS_OK;}//未实现}; COM调用CreateInstance创建请求的对象,参数riid指的是所请求的接口IID,如果这个对象支持这个接口,则增加它的引用计数并返回对自身的引用。 关于代码:本文所提出的方法是如何用纯粹的C编写COM组件的一个大概念。很多方面的细节都省略了。从本文的文字和代码中可以看出用纯C编写COM组件需要做些什么工作,如果你要用这种方法编写COM组件的话,这些代码只能是抛砖引玉,具体的实现可以在此基础上往下做