zoukankan      html  css  js  c++  java
  • 对于SWE相关COM知识的不解

    时间: 14:09 2010-8-19
    PAGE:
    http://www.codeguru.com/Cpp/COM-Tech/activex/tutorials/article.php/c5567
    http://www.codeproject.com/KB/COM/comintro.aspx

    感言: COM 很00,很设计模式

    COM :
    其的接口分离:操作列表
    实现:
    实现类:
    其要求实现接口类,与一些常用的接口.
    其是可以通过接口类继承一些接口,然后在实现类当中统一实现。
    (SWE是就是这样处理的,如自定义控件,我们能否子类化内置控件呢, 不知道,主要是:内置控件其提供了接口

    类,但其没有提供实现类,自定义控件其就提供了相关实现类。
    COM 很00,很设计模式: 内置控件其提供了接口,我们能否使用:装饰者模式来添加新功能(如果对于修改控件的

    外观,其能够在XAML文件当中实现,但用C++我们还很好的实现,思考。。。)


    实现类其一般继承接口类(自定义的)与接口类当中的接口的对应实现类。
    如:
    interface I a : public Ib
    {};

    class a : public Ia, b
    {

    }

    COM 的内部类,其是由a 创建。
    a 其是由一个工厂函数来创建的。(这种设计思想在MS的SWE当中到处可见)

    整个COM 其是放在一个DLL文件当中,
    一个DLL文件当中其可以包含多个COM.
    DLL 文件当中其就有一个工厂函数.

    其一定要创建一个COM CLASS.
    然后通过COM CLASS::QueryInterface(IID,PPV)  来查找接口.
    QueryInterface其是用来打查找接口的,当要查找接口的时候其就可以使用QueryInterface。
    使用COM之前要创建COM对象与查找接口 ,其调用一个工厂函数就能一同实现.

    在一个标准的COM,其是有一个IFactoryClass instance ( 工厂类), 注意工厂类其是用于创建其他对象(COM

    CLASS),而不是自身对象,
    然后COM CLASS 其就可以查找接口.


    HRESULT __stdcall CAddFactory::CreateInstance(IUnknown* pUnknownOuter,
                                               const IID& iid,
                                               void** ppv)
        {

     // Create an instance of the component.

     CAddObj* pObject = new CAddObj ;
     if (pObject == NULL)
         {
      return E_OUTOFMEMORY ;
         }
     // Get the requested interface.
     return pObject->QueryInterface(iid, ppv) ;
        }

    CLIENT 通过CreateInstance(工厂函数)传入IID,就可以查找到接口。

    在SWE当中,其就是以这种思路进行的实现。
    其首先要求控件进行注册,==》 建立一个表。
    CAddObj * pObject = new CAddObj;
    这一步在SWE当中是怎么样实现的.分为两步:
    1. new
    2.Create ( 因为要LOAD XAML ,查找控件的成员,与对于控件相关成员绑定事件)

    最后才是查找接口. 注意其没有使用NEW 而是使用类型转换.

    HRESULT __stdcall CAddObj::QueryInterface(
                                        REFIID riid ,
                                        void **ppObj)
        {
        if (riid == IID_IUnknown)
            {
         *ppObj = static_cast<IAdd*>(this) ;
            AddRef() ;
            return S_OK;
            }

        if (riid == IID_IAdd)
         {
         *ppObj = static_cast<IAdd*>(this) ;
            AddRef() ;
            return S_OK;
         }

        if (riid == IID_IFileIO)
         {
         *ppObj = static_cast<IFileIO*>(this) ;
            AddRef() ;
            return S_OK;
         }

        //
        //if control reaches here then , let the client know that
        //we do not satisfy the required interface
        //

        *ppObj = NULL ;
        return E_NOINTERFACE ;
        }

    我们存储控件,
    我们应该存储哪一个部分呢。是实现类,还是接口

    思考:
    1.
    其为什么只是接口有IID,
    而实现类没有IID,( 其对应于CLSID,好像可以有,也可以没有,所以在XAML2CPP.EXE所生成的代码当中,其没有

    写)

    2.其为什么没有采用这种方式呢,这种形式是什么.
    hr = CoCreateInstance ( CLSID_XXX,         // CLSID of coclass
                            NULL,                    // not used - aggregation
                            CLSCTX_INPROC_SERVER,    // type of server
                            IID_IXXXX,          // IID of interface
                            (void**) &pIXX );        // Pointer to our interface pointer

    DllGetClassObject ==> 其是在DLL当中有IClassFactory.

    CoCreateInstance  其是DLL当中没有IClassFactory的情形,其直接完成IClassFactory的功能.

    STDAPI DllGetClassObject(const CLSID& clsid,
                             const IID& iid,
                             void** ppv)
        {
        //
        //Check if the requested COM object is implemented in this DLL
        //There can be more than 1 COM object implemented in a DLL
        //

        if (clsid == CLSID_AddObject)
            {
            //
            //iid specifies the requested interface for the factory object
            //The client can request for IUnknown, IClassFactory,
            //IClassFactory2
            //
            CAddFactory *pAddFact = new CAddFactory;
            if (pAddFact == NULL)
                return E_OUTOFMEMORY;
            else
                {
                return pAddFact->QueryInterface(iid , ppv);
                }
            }
       

        //
        //if control reaches here then that implies that the object
        //specified by the user is not implemented in this DLL
        //

        return CLASS_E_CLASSNOTAVAILABLE;
        }


    // 在DLLMAIN.CPP 当中,
    其传入CLSID 是CLSID_AddObject,而不是CLSID_FactoryObject,( 因为IFactoryObject 其只是一个接口,而非

    实现类)

    但其创建的对象:CAddFactory *pAddFact = new CAddFactory;
    其的接口IID:IID_IClassFactory OR IID_IUnknown.
    PPV: 其是指向 CAddFactory 而不是CAddObject.

    ==》 以后要调用COM的接口,其要使用调用 CAddFactory::CreateInstance
      然后调用CAddObj::QueryInterface.

     a class ID ,or CLSID ,is  a GUID that names a coclass(short for component object class). an interface ID,or

    IID,is a GUID that names an interface.

    A COM object is an instance of a coclass in memory

    Note that a COM "class" is not the same as a c++ "class"
    a COM class 是由A C++ CLASS 实现的。

    在程序当中怎么样使用了,使用哪一个 class呢,
    如存储

    Create A COM OBJECT ,其就是创建一个C++ OBJECT 吗,
    将C++ OBJECT 赋值给INTERFACE,其就是INTERFACE 类了吗


    every COM interface is derived from IUnkown.
    every COM object(C++ 对象) implements IUnkown.

    QueryInterface() - Requests an interface pointer from a COM object .You use this when a coclass
    implement more than one interface.

    一个COM class 其是一个实现了所有接口的C++ CLASS 吗,
    一个COM CLASS 其是否允许有多个C++ CLASS呢.

    COM 其是采用了很多的设计模式,

    面向接口编程,

    其之所以能够很自然的这样处理是因为,其采用了接口,这是使用很多设计模式的基础.( 如装饰,适配器)

    其当中之所以要引用smartpointer,其就是为了管理new出来的对象,由谁业delete的问题.

    smartpointer : smart,pointer.
    用户将其当作pointer来进行处理。
    smart: 其是用于管理pointer的指针引用 。

    对于接口类的使用,其是通过
    SmartPointer

  • 相关阅读:
    嵌入式工程师C语言面试常见的0x10个问题
    C语言初学者网站推荐
    strlen和sizeof
    基于Docker搭建GitLab和Maven私服
    linux暴露端口可以被外部访问
    MySQL新增用户及赋予权限
    Docker添加域名解析
    Netstat 网络命令详解
    Mysql索引太长导致同步数据结构失败解决方法
    完美解决Cannot download "https://github.com/sass/node-sass/releases/download/binding.nod的问题
  • 原文地址:https://www.cnblogs.com/pengxinglove/p/1809802.html
Copyright © 2011-2022 走看看