和语言无关,可以在 C++ 中用类
的方式来定义。一个 COM 对象可以实现多个接口。
一个特殊的接口,所有COM接口都继承IUnKnown这个接口。
1 interface IUnknown{ 2 HRESULT QueryInterface( // 查询com对象的其他接口指针 3 [in] REFIID iid, // 接口ID 4 [out] void **ppv // 接口指针 5 ); 6 ULONG AddRef(); // 计数+1 7 ULONG Release(); // 计数-1 8 }
mylib.h代码:
1 // 定义一个接口 IAntiCheat 继承 IUnknown 2 __interface IAntiCheat:public IUnknown{ 3 // 接口虚函数 4 virtual BOOL IAntiCheat_PUBG(string& Tag); 5 }; 6 7 // 定义一个类 Inherit 继承 IAntiCheat 接口 8 class Inherit:public IAntiCheat{ 9 public: 10 // 声明 IUnknown 成员 11 virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv); 12 virtual ULONG __stdcall AddRef() { return 0;} 13 virtual ULONG __stdcall Release() { return 0;} 14 15 // 声明自己的虚函数 16 virtual BOOL IAntiCheat_PUBG(string& Tag); 17 }; 18 19 // 声明 CreateInstance 接口创建函数 20 IUnknown* CreateInstance();
mylib.cpp 代码:
1 // 初始化接口ID 2 static const GUID IID_IAntiCheat = {0x4abc66d,0xba5f,0x4e17,{0x82,0xfd,0x98,0x5d,0x9c,0x0,0x73,0xfe}}; 3 4 // 实现自己的接口函数 5 BOOL Inherit::IAntiCheat_PUBG(string& Tag) 6 { 7 // 你的代码... 8 9 return 0; 10 } 11 12 // 实现 QueryInterface 13 HRESULT __stdcall Inherit::QueryInterface(const IID& iid, void** ppv){ 14 // 初始化由 Inherit 重载的 IUnknown 指针 15 IUnknown* pI = static_cast<IAntiCheat*>(new Inherit); 16 17 // 如果 接口ID 符合条件则绑定接口函数 18 if(iid == IID_IAntiCheat){*ppv = static_cast<IAntiCheat*>(pI);} 19 else{ 20 *ppv = NULL; 21 22 // 返回接口对象创建失败标志 23 return E_NOINTERFACE; 24 } 25 26 // 增加计数 27 reinterpret_cast<IUnknown*>(*ppv)->AddRef(); 28 return S_OK; 29 } 30 31 // 实现 CreateInstance 接口创建函数 32 IUnknown* CreateInstance(){ 33 // 初始化由 Inherit 重载的 IUnknown 指针 34 IUnknown* pI = static_cast<IAntiCheat*>(new Inherit); 35 36 // 增加计数 37 pI->AddRef(); 38 39 return pI ; 40 }
test.h 代码:
// 同 mylib.h
test.cpp 代码:
1 int _tmain(int argc, _TCHAR* argv[]) 2 { 3 // 初始化接口ID 4 static const GUID IID_IAntiCheat = {0x4abc66d,0xba5f,0x4e17,{0x82,0xfd,0x98,0x5d,0x9c,0x0,0x73,0xfe}}; 5 6 // 创建接口 7 IUnknown* pIUnknown = CreateInstance(); 8 9 // 调用 QueryInterface,获取接口类指针 10 IAntiCheat* pIAntiCheat = NULL; 11 HRESULT hr = pIUnknown->QueryInterface( 12 IID_IAntiCheat, 13 (void**)&pIAntiCheat 14 ); 15 // 判断 QueryInterface 是否执行成功 16 if (SUCCEEDED(hr)){ 17 // 调用你的接口函数 18 string Tag; 19 pIAntiCheat->IAntiCheat_PUBG(Tag); 20 } 21 22 getchar(); 23 return 0; 24 }