com聚合有关问题讨论
com聚合问题讨论
------解决方案--------------------
QueryInterface//开始查询接口,都没有com对象,查了作甚?
com对象可以在 QueryInterface时创建
增加了m_ref的次数,有什么用呢?无用啊
引用计数是COM基础的概念, 返回接口的指针, 就应该为该接口做保留, 否则工厂释放后, 接口就没了
前面的问题也是一样的道理
------解决方案--------------------
潘爱民写这本书的时候感觉不怎么懂com,反正我是翻了几页实在看不下去
找些国外的书和文章,东拼西凑下,然后自己做做实验,典型的中国式论文
- C/C++ code
聚合技术问题讨论 两个com对象A和B,A被B聚合。 当然A也可以不被聚合,所以 与A相关有了2个接口,一个非委托,一个委托 非委托接口: INondelegatingUnknown 委托接口:ISomeInterface class CA : public ISomeInterface, public INondelegatingUnknown { protected: ULONG m_Ref; public: CA(IUnknown *pUnknownOuter); ~CA(); public : // Delegating IUnknown virtual HRESULT __stdcall QueryInterface(const IID& iid, void **ppv) ; virtual ULONG __stdcall AddRef() ; virtual ULONG __stdcall Release() ; // Nondelegating IUnknown virtual HRESULT __stdcall NondelegationQueryInterface(const IID& iid, void **ppv); virtual ULONG __stdcall NondelegatingAddRef(); virtual ULONG __stdcall NondelegationRelease(); virtual HRESULT __stdcall SomeFunction( ) ; private : IUnknown *m_pUnknownOuter; // pointer to outer IUnknown }; 所以我们需要实现6个接口,这样才能给其他人或者自己继续开发. 其中的一个函数:QueryInterface的实现,我有疑问: CA::QueryInterface 是一个查询接口的函数, 其大致流程为: 1.如果为聚合指针不为空,则进行使用聚合对象查询 2.如果聚合指针为空,则进行非委托查询NondelegationQueryInteface 代码为: HRESULT CA::QueryInterface(const IID& iid, void **ppv) { if ( m_pUnknownOuter != NULL ) return m_pUnknownOuter->QueryInterface(iid, ppv); //实际上会被聚合对象B调用!!! else return NondelegationQueryInterface(iid, ppv); //非委托查询 } 问题出来了: 非委托查询函数,何苦 分2种情形? 看代码: (class CA:public INondelegatingUnknown,ISomeInterface) HRESULT CA::NondelegationQueryInterface(const IID& iid, void **ppv) { if ( iid == IID_IUnknown ) { *ppv = (INondelegatingUnknown *) this ; ((IUnknown *)(*ppv))->AddRef() ; //1种 } else if ( iid == IID_SomeInterface ) { *ppv = (ISomeInterface *) this ; ((ISomeInterface *)(*ppv))->AddRef() ; //2种 } else { *ppv = NULL; return E_NOINTERFACE ; } return S_OK; } 何苦非两种? 3. 工厂类中的 中的m_ref到底有什么用? 为什么在DllGetClassObject 中创建工厂对象后, 立即查询接口,殊不知查询接口的代码很奇怪?(为什么说其诡异, 原因是: 尽管你有了工厂对象,但是 你没有创建com对象A啊, 增加次数m_ref有什么用呢?) extern "C" HRESULT __stdcall DllGetClassObject(const CLSID& clsid, const IID& iid, void **ppv) { if (clsid == CLSID_CompA) { CAFactory *pFactory = new CAFactory; //只有工厂对象,没有com对象!!! if (pFactory == NULL) { return E_OUTOFMEMORY ; } HRESULT result = pFactory->QueryInterface(iid, ppv); //开始查询接口,都没有com对象,查了作甚? return result; } else { return CLASS_E_CLASSNOTAVAILABLE; } } class CAFactory : public IClassFactory { protected: ULONG m_Ref; //look here ..................... //IUnknown members HRESULT __stdcall QueryInterface(const IID& iid, void **ppv); ULONG __stdcall AddRef(); ULONG __stdcall Release(); }; 以下是CAFactory::QueryInterface的代码: HRESULT CAFactory::QueryInterface(const IID& iid, void **ppv) { if ( iid == IID_IUnknown ) { *ppv = (IUnknown *) this ; ((IUnknown *)(*ppv))->AddRef() ; //增加了m_ref的次数,有什么用呢?无用啊 } else if ( iid == IID_IClassFactory) { *ppv = (IClassFactory *) this ; ((IClassFactory *)(*ppv))->AddRef() ; //同理这里也是 } else { *ppv = NULL; return E_NOINTERFACE ; } return S_OK; } 以上代码 来自 com原理与应用
------解决方案--------------------
QueryInterface//开始查询接口,都没有com对象,查了作甚?
com对象可以在 QueryInterface时创建
增加了m_ref的次数,有什么用呢?无用啊
引用计数是COM基础的概念, 返回接口的指针, 就应该为该接口做保留, 否则工厂释放后, 接口就没了
前面的问题也是一样的道理
------解决方案--------------------
潘爱民写这本书的时候感觉不怎么懂com,反正我是翻了几页实在看不下去
找些国外的书和文章,东拼西凑下,然后自己做做实验,典型的中国式论文