ATL通过模板类来创建COM对象,如果我想重载在ATL的类厂的CreateInstance,并在
其中添加自己的代码,能否实现以及如何实现?

解决方案 »

  1.   

    暂时改写CComClassFactory,编译完以后改回来。
      

  2.   

    写ds的filter是可以重写cocreateinstance,找网上的例子看看GZ
      

  3.   

    还是说说你的具体需求。仅仅是要“重载在ATL的类厂的CreateInstance”,
    那么“重载”就意味着“继承”,需要修改ATL的源代码。
      

  4.   

    一般用户创建COM对象,是通过class Factory来实现,缺省状态下每一个用户创建一次对象,class Factory会new object来返回用户,这样存在一下问题:
       1 如果我想无论多少用户调用CreateInstance,我只返回一个object给用户,这样我可以在object 里面共享数据。
       2 缺省状态下,ATL 的COM对象构造函数没有参数,那么我想在COM对象中按照自己的要求初始化一些参数传递给用户就无法实现。因为ATL封装了CreateInstance,那么我无法控制对象的创建,对象初始化就无法实现。
      

  5.   

    使用共享数据有很多种方式,比如创建共享数据段(com也是dll啊),或者共享内存等等。其实你不用每次都Create,当你第一次创建对象时,使用CoRegisterClassObject将其注册到系统种,以后创建时先CoGetObject一下试试,如果没有得到再创建,如果有就直接使用得到的接口。这样就不用改ATL了,只是操作几个API就行了
      

  6.   

    一般用户创建COM对象,是通过class Factory来实现,缺省状态下每一个用户创建一次对象,class Factory会new object来返回用户,这样存在一下问题:
    1 如果我想无论多少用户调用CreateInstance,我只返回一个object给用户,这样我可以在object 里面共享数据。
    2 缺省状态下,ATL 的COM对象构造函数没有参数,那么我想在COM对象中按照自己的要求初始化一些参数传递给用户就无法实现。因为ATL封装了CreateInstance,那么我无法控制对象的创建,对象初始化就无法实现。
    ------------------------
    那自己可以在封装一层啊,那样的话,不管你要实现单构件也好,自定义参数也好,就都可以了。
      

  7.   

    类厂函数在ATL里是可以重写的首先在你的组件内声明:
     DECLARE_CLASSFACTORY_EX(CLASS) 
     注意:这里的CLASS应该从CComClassFactory派生,并且改写了CreateInstance
    这样就实现了自定义类厂举例:
    Class CYourClass : public CComCoClass(....)
    {
       DECLARE_CLASSFACTORY_EX(CYourClassFactory)
    }
    class CYourClassFactory : public CComClassFactory
    {
        //在这里改写CreateInstance,就可以实现自定义类厂
    }
      

  8.   

    这方面在深入解析ATL中有P200左右,有比较详细的介绍唯一感慨的就是搞ATL,COM的程序员
    这本书都没有几个人认真读过(也包括我)
      

  9.   

    一般用户创建COM对象,是通过class Factory来实现,缺省状态下每一个用户创建一次对象,class Factory会new object来返回用户,这样存在一下问题:
       1 如果我想无论多少用户调用CreateInstance,我只返回一个object给用户,这样我可以在object 里面共享数据。
    ====================================================================================
    DECLARE_CLASSFACTORY_SINGLETON
    这个宏决定类厂为该对象创建一个全局唯一对象
       2 缺省状态下,ATL 的COM对象构造函数没有参数,那么我想在COM对象中按照自己的要求初始化一些参数传递给用户就无法实现。因为ATL封装了CreateInstance,那么我无法控制对象的创建,对象初始化就无法实现。
    =====================================================================================
    类厂的CreateInstance 可以视为一个 new 操作,你可以对他初始化后再返回用户.
    至于进程外那是不可以的.
    sample : HRESULT  MyObj::NewItem( IItem** ppItem )
    {
         CItem *  pItem = NULL;
         CComObject<CItem>::CreateInstance(&pItem);
        pItem->m_Member = ?
        *ppItem = pItem;
       return S_OK;
    }
      

  10.   

    补充:
    其实问题正如楼上所说
    类厂的CreateInstance 所做的工作无外乎NEW出几个对象来(在你的BEGIN_OBJECT_MAP中列出的可创建类)
    在ATL里类厂的CreateInstance是利用pfnGetClassObject(类似)函数指针引用的,问题简化为,不过是一个函数指针指向的问题了
    DECLARE_CLASSFACTORY_SINGLETON这种方式不推荐~~~~~~
      

  11.   

    使用DECLARE_CLASSFACTORY_SINGLETON可以了,这时候类厂创建组件实例(CComObjectGlobal)后会缓存一个引用,后续激活要求都是返回这个引用,这样就确保了进程内组件实例的唯一性。
      

  12.   

    Singleton 对象 只实例化一次的对象。后续激活得到的都是同一个对象的接口指针例如:
    可能会有 10 个客户端调用 CoCreateInstance 来“创建”Singleton 对象,但实际上,它们都是接收指向同一对象的接口指针产生的问题:(针对In Proc)
    1.这个时候安全,和并发都会产生问题
      因为10个客户端拥有同一个对象的接口指针,对象怎么保存每个客户的用户自己的状态那?
      所以实现这些都很麻烦,这是不推荐使用之一2.正如“深入解析ATL”所述
      inproc singleton不能要求线程相依性,必须是线程安全而且是套间无关的
      问题就来了
      如果你的组件是STA,STA本身就具有线程相依性,这意味着什么呢?
      客户端的套间模型必须为MultiThread所以DECLARE_CLASSFACTORY_SINGLETON慎用,或不推荐,因为会有更好的替代方法
    如果是本地服务orNT服务还可以考虑
      

  13.   

    组件的套间模型对于客户来说是透明的,客户完全不用考虑组件的同步和重入性质,对于SINGLETON的组件来说,如果是single或sta的套间类型,完全不用考虑线程安全的问题,因为只有一个线程可访问唯一的对象实例,所以只需要同步模块中全局变量(比如模块和类厂的引用计数)的访问就可以了,对于可有多实例的STA组件,静态成员也要同步,而MTA的组件所有成员和用到的全局变量都要同步。
      

  14.   

    1.引自:XXandOO(麦猪) 的 只有一个线程可访问唯一的对象实例
    我的观点:这句话是对的
    举例:
    银行有10个柜台给顾客”同步“服务,用了singleton后,产生的结果是,虽然你银行有10个柜台,但同时只有一个,唯一的一个为客户提供服务,天啊,客户不得把银行给砸了2.引自:XXandOO(麦猪) 的如果是single或sta的套间类型,完全不用考虑线程安全的问题
    我的观点:这句话是不负责任的
    背景:组件线程模型是STA,以singleton方式,生存的环境也是STA,也就是说你是用STA的方式创建你的组件,YEAH,STA可是线程安全的啊,马上你就会倒霉了~~~~注意:无论在多少个线程里创建你的组件,现在其实都是一个,而在每一个初始化STA      后,这个线程将直接拥有你真实的组件,所有的线程拥有的其实都是这一个举例:如果你有2个方法SetCounts(.....)和GetCounts(......)
    情况(1):如果只有一个对象 SetCounts(+10W(存)) 立刻 GetCounts())不会有任何问题情况(2):问题就来了,现在有2个线程
    SetCounts(+10W(存)),你很开心
         -------SetCounts(-10000W(取)) 另外一个线程同步做的
    GetCounts()天啊,我的钱呢?我刚存完啊,怎么了??????
      

  15.   

    to loverx(烟花):
    我可没有和你叫板的意思,呵呵。
    当singleton生存在STA时,只有创建组件的线程可以访问组件,注意STA有一个内置的消息循环,虽然别的线程也得到了一个组件的指针,但是这个指针并不是直接访问组件的指针,而是一个代理指针,这时非创建线程永远不可能访问到组件,而是向创建线程的消息循环插入一项,由创建线程来代之访问组件,所以这时的组件相当于一个单线程类,所以不需要同步(除全局变量外)。
    至于你的钱,你既然决定存入一个共享帐户,当然可被别人提走,同步指的是不能两个人同时存或取,而依次存取显然是合理的。