 
- UID
- 872238
|

本文提供一个完全用C++实现的进程内(DLL)COM服务器,不要ATL或MFC提供任何支持。用这种方式编写COM对象可以让你深入地洞察到COM处理进程内服务器的方法以及COM是如何创建类工厂的。利用本文提供的这个简单框架你可以实现很基本的COM组件,如外壳扩展(Shell Extensions)等。
以下是用本文所说的方式编写自己的COM对象要经过的步骤:
第一步:写一个头文件,这个头文件包含以下内容:
1、 包含文件comdef.h:#include <comdef.h>。
2、 定义COM服务器的GUID。
_declspec(selectany) GUID CLSID_Mine = { 0xdc186800, - 0x657f, 0x11d4,
- {0xb0, 0xb5, 0x0, 0x50, 0xba, 0xbf, 0xc9, 0x4}
- };
3、 给出接口的IID以及这个接口要实现的方法定义。到时客户端会用到这个接口的IID和接口的方法。
interface __declspec(uuid("F614FB00-6702-11d4-B0B7-0050BABFC904")) ImyInterface : public IUnknown - { STDMETHOD(Square)(long *pVal)PURE;
- STDMETHOD(Cube)(long *pVal)PURE;
- };
客户端使用此接口:
HRESULT hr; - ImyInterface *pmine=(0); hr = CoCreateInstance(CLSID_Mine, // COM 服务器的CLSID
- NULL, //不支持聚合 CLSCTX_INPROC_SERVER, // 是个DLL
- __uuidof(ImyInterface), // 接口的IID (void**)&pmine
- );
还有一种方法可以从注册表中获得COM对象的CLSID,就是调用CLSIDFromProgId()函数,不过必须把组件的ProgId传递给这个函数。
第二步:必须为所定义的接口提供实现,本文用的方法是创建一个从接口继承的新类:
// 这个类实现单接口ImyInterface ... - // //
- class CmyInterface : public CComBase<> , public InterfaceImpl<ImyInterface>
- { public:
- CmyInterface(); virtual ~CmyInterface();
- // 我们必须要为QueryInterface 编写代码 STDMETHOD(QueryInterface)(REFIID riid,LPVOID *ppv);
- // ImyInterface 接口方法 STDMETHOD(Square)(long *pVal);
- STDMETHOD(Cube)(long *pVal);
- };
模版类InterfaceImpl<>提供接口引用计数的实现。在此我们可以用多接口继承,那样就能在一个COM组件中实现多个接口。
第三步:在完成这个对象之前,我们还要编写Queryinterface和两个接口方法:
STDMETHODIMP CmyInterface: ueryInterface(REFIID riid,LPVOID *ppv) - { *ppv = NULL;
- if(IsEqualIID(riid,IID_IUnknown) || IsEqualIID(riid,__uuidof(ImyInterface))) {
- // 因为我们从ImyInterface继承,所以要进行强制类型转换 *ppv = (ImyInterface *) this;
- _AddRef(); // 这个方法从某个基类继承而来
- return S_OK; }
- return E_NOINTERFACE; }
- STDMETHODIMP CmyInterface::Square(long *pVal)
- { long value = *pVal;
- *pVal = value * value; return S_OK;
- }
- STDMETHODIMP CmyInterface::Cube(long *pVal) {
- long value = *pVal; *pVal = value * value * value;
- return S_OK;
- }
|
|