COM接口必须得提供给客户程序,这样他们才能知道你的这个DLL存在什么样的函数实现什么样的功能,同时还需要一个GUID和接口ID。COM的接口你可以把它当成一个虚类处理。
定义接口如下:mycom.h
- #pragma once
- #include "unknwn.h"
- // {85F5CF11-2A25-4ef9-8F7C-8C3F14A0860A}
- static const GUID CLSID_MyCOM =
- { 0x85f5cf11, 0x2a25, 0x4ef9, { 0x8f, 0x7c, 0x8c, 0x3f, 0x14, 0xa0, 0x86, 0xa } };
- // {07C4A7BC-BBD1-4ced-80A5-A76377929F35}
- static const IID IID_ITest =
- { 0x7c4a7bc, 0xbbd1, 0x4ced, { 0x80, 0xa5, 0xa7, 0x63, 0x77, 0x92, 0x9f, 0x35 } };
- interface ITest : public IUnknown
- {
- STDMETHOD (Add)(int nOp1, int nOp2, int* pret) PURE;
- };
接口实现如下:test.h
- #pragma once
- #include "mycom.h"
- extern LONG g_cLock; // # of outstanding objects
- class CTest :
- public ITest
- {
- public:
- CTest(void);
- virtual ~CTest(void);
- public:
- // IUnknown members
- //@cmember Request an Interface
- STDMETHODIMP QueryInterface(REFIID, LPVOID *);
- //@cmember Increments the Reference count
- STDMETHODIMP_(ULONG) AddRef(void);
- //@cmember Decrements the Reference count
- STDMETHODIMP_(ULONG) Release(void);
- STDMETHOD (Add)(int nOp1, int nOp2, int* pret);
- protected:
- //@cmember Reference count
- ULONG m_cRef;
- };
test.cpp
- #include "stdafx.h"
- #include "test.h"
- CTest::CTest(void)
- {
- m_cRef = 0;
- InterlockedIncrement(&g_cLock);
- }
- CTest::~CTest(void)
- {
- InterlockedDecrement(&g_cLock);
- }
- STDMETHODIMP CTest::QueryInterface(REFIID riid, void **ppv)
- {
- if(!ppv)
- return E_INVALIDARG;
- *ppv = NULL;
- if(riid == IID_IUnknown || riid == IID_ITest)
- *ppv = (LPVOID) this;
- if(*ppv == 0)
- return E_NOINTERFACE;
- ((LPUNKNOWN)*ppv)->AddRef();
- return S_OK;
- }
- STDMETHODIMP_(ULONG) CTest::AddRef()
- {
- return ++m_cRef;
- }
- STDMETHODIMP_(ULONG) CTest::Release()
- {
- if(!--m_cRef)
- delete this;
- return m_cRef;
- }
- STDMETHODIMP CTest::Add(int nOp1, int nOp2,int * pret)
- {
- *pret = nOp1 + nOp2;
- return S_OK;
- }
将接口加入mycom中:factory.cpp
- #include "test.h"
- STDMETHODIMP CClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv)
- {
- HRESULT hrRet;
- CTest* pTest = 0;
- if(NULL != pUnkOuter)
- return CLASS_E_NOAGGREGATION;
- if(IsBadWritePtr(ppv, sizeof(void*)))
- return E_POINTER;
- pTest = new CTest;
- if(NULL == pTest)
- return E_OUTOFMEMORY;
- hrRet = pTest->QueryInterface(riid, ppv);
- if(FAILED(hrRet))
- delete pTest;
- return hrRet;
- }
至此一个简单的COM进程内组件实现完成,其提供的接口是ITest,客户程序可以通过这个接口调用CTest::Add函数。