COM:对象组件模型
和语言无关,可以在 C++ 中用类
的方式来定义。一个 COM 对象可以实现多个接口。
IUnknown:未直接口
一个特殊的接口,所有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 }