C++ 实现 COM → IUnknown → 接口

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 }

 

上一篇:2022.01.13LeetCode每日一题——至少是其他数字两倍的最大数


下一篇:浮动