zoukankan      html  css  js  c++  java
  • 最简单的COM实现例子

    收藏一个例子,摘自http://www.cnblogs.com/gamedes/archive/2013/01/17/2863964.html#2602071

    #include "stdio.h"
    
    class IUnknow
    {
    public: 
     virtual void * QueryInterface( int _type ) = 0;
     virtual void addRef( void ) = 0;
     virtual void release( void ) = 0;
    };
    
    class IX : public IUnknow
    {
    public: 
     virtual void X1( void ) = 0;
     virtual void X2( void ) = 0;
    };
    
    class IY : public IUnknow
    {
    public:
     
     virtual void Y1( void ) = 0;
     virtual void Y2( void ) = 0;
    };
    
    
    class CA : public IX, public IY
    {
    public: 
        CA( ) : m_ref( 0 ) { }
     
    public: 
        void * QueryInterface( int _type )
        {
            void * _interface = NULL;
      
            if( 1 == _type ) _interface = static_cast< IX * >( this );
            else if( 2 == _type ) _interface = static_cast< IY * >( this );
      
            if( _interface ) static_cast< IUnknow * >( _interface )->addRef( );
            return _interface;
        }
     
        void addRef( void ){ m_ref ++; }
        void release( void )
     {
      m_ref --; 
      if( m_ref <= 0 )
      { 
       delete this; 
       printf( "Component destroy ... \n" ); 
      } 
     }
     
        void X1( void ){ printf( "X1( )\n" ); }
        void X2( void ){ printf( "X2( )\n" ); }
        void Y1( void ){ printf( "Y1( )\n" ); }
        void Y2( void ){ printf( "Y2( )\n" ); }
     
    private: 
        int m_ref;
    };
    
    IUnknow * CreateInstance( void )
    {
        IUnknow * _interface = static_cast< IX * >( new CA );
     
        _interface->addRef( );
     
        return _interface;
    }
    
    int main( int argc, char * argv[ ] )
    {
        IUnknow * obj = CreateInstance( );
        {
            IX * ix = ( IX * ) obj->QueryInterface( 1 );
            {
                ix->X1( );
                ix->X2( );
            }
            ix->release( );
      
            IY * iy = ( IY * ) obj->QueryInterface( 2 );
            {
                iy->Y1( );
                iy->Y2( );
            }
            iy->release( );
        }
        obj->release( );
     
        return 0;
    }

    我还是解释一下吧 :

    IUnknow 是所有接口的祖先,因此,任何一个接口,都可以通过 QueryInterface 来获得一个组件所支持的所有其它接口 。

    addRef 和 release 用于统计引用计数器,来控制组件的生命周期 。

    CA 就是我们的接口实现主体,也就是接口的集合,我们称它作 —— 组件 。

    CreateInstance 用于创建我们的组件,它相当于我们 D3D 的 Direct3DCreate9  这样子的函数,嗯 ... hgeCreate 也是这样子的函数(笑) 。

    最后最重要的一条 :

    IX 和 IY 才是接口,才是我们客户能够进行交互的实体,因为对于客户来说,CA 组件是不可见的,客户只知道拥有 IX 和 IY 接口,其余东西,都是透明的 。

    当然,真正的 COM 可不会像这个样子,它至少,还需要一个 GUID 啊、CLSID 啊、IID 之类的东西,不过我上面都用 1 和 2 简单地代替了 。

    其次,我有一个疑惑,就像上面的代码里面,在查询得到 IX 接口之后, CA 的引用计数器应该为 2,我们用完了 IX 接口,release 一次之后,CA 的引用计数器应该为 1,此时 CA 还没有被销毁,我们应该还能继续使用 IX 接口,但是真正的 COM 是否也可以这样,这点我就没试过了,如果各位读者知道为何的话,还请不啬指点一二哈 ~~ 

  • 相关阅读:
    50多条mysql数据库优化建议
    反向代理|与正向代理区别区别
    CDN技术
    mysql存储过程对900w数据进行操作测试
    Navicat For Mysql快捷键
    Linux下目标文件分析
    Linux下的两个经典宏定义 转
    debuginfo-install glibc-2.17-157.el7.x86_64
    index merge 引起的死锁分析
    linux内核源码中常见宏定义
  • 原文地址:https://www.cnblogs.com/Roarsun/p/2864571.html
Copyright © 2011-2022 走看看