进程内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

相关文章

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

Java实现将byte[]转换为File对象

《Java实现将byte[]转换为File对象》这篇文章将通过一个简单的例子为大家演示Java如何实现byte[]转换为File对象,并将其上传到外部服务器,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言1. 问题背景2. 环境准备3. 实现步骤3.1 从 URL 获取图片字节数据3.2 将字节数组

Windows命令之tasklist命令用法详解(Windows查看进程)

《Windows命令之tasklist命令用法详解(Windows查看进程)》tasklist命令显示本地计算机或远程计算机上当前正在运行的进程列表,命令结合筛选器一起使用,可以按照我们的需求进行过滤... 目录命令帮助1、基本使用2、执行原理2.1、tasklist命令无法使用3、筛选器3.1、根据PID

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us

Javascript访问Promise对象返回值的操作方法

《Javascript访问Promise对象返回值的操作方法》这篇文章介绍了如何在JavaScript中使用Promise对象来处理异步操作,通过使用fetch()方法和Promise对象,我们可以从... 目录在Javascript中,什么是Promise1- then() 链式操作2- 在之后的代码中使

MyBatis的配置对象Configuration作用及说明

《MyBatis的配置对象Configuration作用及说明》MyBatis的Configuration对象是MyBatis的核心配置对象,它包含了MyBatis运行时所需的几乎所有配置信息,这个对... 目录MyBATis配置对象Configuration作用Configuration 对象的主要作用C

Spring AI集成DeepSeek三步搞定Java智能应用的详细过程

《SpringAI集成DeepSeek三步搞定Java智能应用的详细过程》本文介绍了如何使用SpringAI集成DeepSeek,一个国内顶尖的多模态大模型,SpringAI提供了一套统一的接口,简... 目录DeepSeek 介绍Spring AI 是什么?Spring AI 的主要功能包括1、环境准备2

SpringBoot实现导出复杂对象到Excel文件

《SpringBoot实现导出复杂对象到Excel文件》这篇文章主要为大家详细介绍了如何使用Hutool和EasyExcel两种方式来实现在SpringBoot项目中导出复杂对象到Excel文件,需要... 在Spring Boot项目中导出复杂对象到Excel文件,可以利用Hutool或EasyExcel

linux本机进程间通信之UDS详解

《linux本机进程间通信之UDS详解》文章介绍了Unix域套接字(UDS)的使用方法,这是一种在同一台主机上不同进程间通信的方式,UDS支持三种套接字类型:SOCK_STREAM、SOCK_DGRA... 目录基础概念本机进程间通信socket实现AF_INET数据收发示意图AF_Unix数据收发流程图A

SpringBoot集成图片验证码框架easy-captcha的详细过程

《SpringBoot集成图片验证码框架easy-captcha的详细过程》本文介绍了如何将Easy-Captcha框架集成到SpringBoot项目中,实现图片验证码功能,Easy-Captcha是... 目录SpringBoot集成图片验证码框架easy-captcha一、引言二、依赖三、代码1. Ea