进程内COM对象的创建过程(AC5)

2024-03-05 03:48
文章标签 创建 对象 进程 过程 com ac5

本文主要是介绍进程内COM对象的创建过程(AC5),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AC5,由VS2005的ATL向导生成的默认COM对象代码分析ATL如何实现COM,第五部分。

  Com库创建COM对象可以使用三个方法:

[csharp]  view plain copy
  1. CoCreateInstance(IN REFCLSID rclsid, IN LPUNKNOWN pUnkOuter, IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID FAR* ppv);  
  2.   
  3. CoCreateInstanceEx(IN REFCLSID Clsid, IN IUnknown * punkOuter, IN DWORD dwClsCtx, IN COSERVERINFO * pServerInfo, IN DWORD dwCount, IN OUT MULTI_QI * pResults );  
  4.   
  5. CoGetClassObject(IN REFCLSID rclsid, IN DWORD dwClsContext, IN LPVOID pvReserved, IN REFIID riid, OUT LPVOID FAR* ppv);  

  常用的是CoCreateInstance,内部实现上,CoCreateInstance和CoCreateInstanceEx都先调用CoGetClassObject,可以说,CoGetClassObject是Com库创建com对象第一个被调用的方法。

  具体的调用过程是这样的:  

  1.CoCreateInstance调用CoGetClassObject函数

   2.COM库找到dll程序并进入进程

   3.调用DllGetClassObject函数

   4.DllGetClassObject函数创建类厂

   5.DllGetClassObject函数把类厂接口返回给CoGetClassObject函数

   6.CoGetClassObject函数把类厂返回给CoCreateInstance函数

   7.CoCreateInstace函数得到类厂后,调用类厂的对象创建函数

   8.类厂创建COM对象

   9.类厂把COM对象返回给CoCreateInstance函数,CoCreateInstance函数返回

   10.客户直接调用COM对象 

  从ATL COM服务器的角度上来说:

  加载dll阶段

  1._DllMainCRTStartup

   2.DoInitialization初始化CAtlComModule、_AtlBaseModule、_AtlWinModule、_Module

   3.CoCreateInstance调用CoGetClassObject函数

  4.dll函数DllGetClassObject被调用

  5.转到_AtlModule.DllGetClassObject(CAtlDllModuleT< Your_COM_Module >::DllGetClassObject)

   6.CAtlDllModuleT< Your_COM_Module >:: GetClassObject

  7.ATLAPI AtlComModuleGetClassObject(&_AtlComModule作为pComModule参数)

  8.找到预先保存的ATL¥__m中的_ATL_OBJMAP_ENTRY指针

  9.XXX:: _ClassFactoryCreatorClass::CreateInstance(通过映射表获得)

  10.CComCreator:: CreateInstance

   11.new CComObjectCached< CComClassFactory >

   12.给CComClassFactory对象设置创建com对象方法(SetVoid方法设置了CreateInstance里要使用到的指针,别忘了CComClassFactory的CreateInstance是非静态的)

  13.CComClassFactory对象的IUnknown接口(使用了QI方法)其实就是IClassFactory的IUnknow接口了

  14.使用IClassFactory的IUnknown查询到IClassFactory接口

  15.逐层返回到DllGetClassObject

  16.CoCreateInstance得到了类厂接口

  17.CoCreateInstance调用类厂的CreateInstance方法(该CreateInstance非静态,所以必须使用类厂接口调用)

  18.因为之前我们已经给类厂对象保存了com对象的CreateInstance指针(该方法为静态,在CoComCreator2中),所以CoComCreator2直接向两个CoComCreator转发CreateInstance请求。(根据pOuter,如果非聚合,使用CComObject,聚合的话,则使用CComAggObject)

  19.(不聚合)CComObject<XXX>::CreateInstance(该方法为静态方法),该类不处理聚合情况,所以pOuter传入NUL

   19.(聚合)CComAggObject同CComObject相比,不同点在QI,CComObject是自己直接调用查询方法,而CComAggObject则是把请求转发给pOuter,在CComAggObject的构造函数中,pOuter被赋值给了m_contained,该指针类型为CComContainedObject<contained>,实际转发工作由这个类完成。通过_InternalQueryInterface,对,我说过定义这个函数的宏。

  20.(不聚合)按照CoComCreator的定式,调用setVoid方法,但CoComObject没有定义setVoid方法,所以向基类XXX求助,XXX转向CComObjectRootEx而后CComObjectRootBase,终于找到了setVoid方法。(可惜这个方法什么也不做,不过我们传递的参数也是NUL,互相“欺诈”贝丷丷)

  21.CComCreator例行公事的调用了_AtlInitialConstruct 、FinalConstruct、_AtlFinalConstruct方法,当然这些方法都是“欺诈行为”,不过可喜的是FinalConstruct在我们定义的类里,我们可以在这里定制一些初始化时的行为。

   22.CComCreator调用QI方法,这次传递的参数是我们在使用CoCreateInstance时传递的参数,因而用户的接口查询请求在这里完成。

这篇关于进程内COM对象的创建过程(AC5)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/775242

相关文章

将图片导入Python的turtle库的详细过程

《将图片导入Python的turtle库的详细过程》在Python编程的世界里,turtle库以其简单易用、图形化交互的特点,深受初学者喜爱,随着项目的复杂度增加,仅仅依靠线条和颜色来绘制图形可能已经... 目录开篇引言正文剖析1. 理解基础:Turtle库的工作原理2. 图片格式与支持3. 实现步骤详解第

Linux系统调试之ltrace工具使用与调试过程

《Linux系统调试之ltrace工具使用与调试过程》:本文主要介绍Linux系统调试之ltrace工具使用与调试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、ltrace 定义与作用二、ltrace 工作原理1. 劫持进程的 PLT/GOT 表2. 重定

Java 如何创建和使用ExecutorService

《Java如何创建和使用ExecutorService》ExecutorService是Java中用来管理和执行多线程任务的一种高级工具,可以有效地管理线程的生命周期和任务的执行过程,特别是在需要处... 目录一、什么是ExecutorService?二、ExecutorService的核心功能三、如何创建

Maven 依赖发布与仓库治理的过程解析

《Maven依赖发布与仓库治理的过程解析》:本文主要介绍Maven依赖发布与仓库治理的过程解析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下... 目录Maven 依赖发布与仓库治理引言第一章:distributionManagement配置的工程化实践1

Spring三级缓存解决循环依赖的解析过程

《Spring三级缓存解决循环依赖的解析过程》:本文主要介绍Spring三级缓存解决循环依赖的解析过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、循环依赖场景二、三级缓存定义三、解决流程(以ServiceA和ServiceB为例)四、关键机制详解五、设计约

spring IOC的理解之原理和实现过程

《springIOC的理解之原理和实现过程》:本文主要介绍springIOC的理解之原理和实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、IoC 核心概念二、核心原理1. 容器架构2. 核心组件3. 工作流程三、关键实现机制1. Bean生命周期2.

Redis实现分布式锁全解析之从原理到实践过程

《Redis实现分布式锁全解析之从原理到实践过程》:本文主要介绍Redis实现分布式锁全解析之从原理到实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景介绍二、解决方案(一)使用 SETNX 命令(二)设置锁的过期时间(三)解决锁的误删问题(四)Re

使用Python创建一个功能完整的Windows风格计算器程序

《使用Python创建一个功能完整的Windows风格计算器程序》:本文主要介绍如何使用Python和Tkinter创建一个功能完整的Windows风格计算器程序,包括基本运算、高级科学计算(如三... 目录python实现Windows系统计算器程序(含高级功能)1. 使用Tkinter实现基础计算器2.

SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法

《SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法》在SQLyog中执行存储过程时出现的前置缩进问题,实际上反映了SQLyog对SQL语句解析的一个特殊行为,本文给大家介绍了详... 目录问题根源正确写法示例永久解决方案为什么命令行不受影响?最佳实践建议问题根源SQLyog的语句分

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设