zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    文件类型的判断
    VS 2003 源码配置管理(subversion+apache)
    DataView
    sql server 挂起的文件操作
    关于权限设计的轻量级实现
    各种类型文件在SQL Server中存储的解决方案
    免费或开源的项目管理工具
    UML中的用例(Use Case)概念分析及实例
    大对象的存储
    用js实现同一页面多个运动效果
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/15148262.html
Copyright © 2011-2022 走看看