COM客户端连接COM服务器所需的文件是什么(进程外方案)?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了COM客户端连接COM服务器所需的文件是什么(进程外方案)?相关的知识,希望对你有一定的参考价值。

我想了解本文中提到的文件的目的,并将知识链接到我当前的COM服务器和COM客户端场景,以便我可以实现我的COM服务器以使用COM服务器:this

我有一个COM服务器,它是一个在后台运行的exe或服务。目前,我知道有一个从IUnknown和IDispatch继承的公开接口。此外,我还生成了以下文件:

  1. xxx_i.c定义了所有CLSID和IID
  2. xxx_i.h定义了接口支持的所有方法
  3. xxx_p.c?
  4. dlldata.c?

我现在使用自动化方式IDispatch - > Invoke()来访问接口方法。虽然这种方式似乎没有使用上面提到的任何文件,但我仍然希望了解它们的目的,同时使用常规方法IUnknown - > QueryInterface()来访问方法。

由于我是COM世界的新手,任何建议的阅读都将不胜感激!谢谢!

答案

在最简单的形式中,COM只是vtable二进制合约加上所有接口的母亲:IUnknown。 COM是一种在没有源代码的情况下重用代码的方法,使用组件,它是某种动态的转换机制。如果我知道你支持的coclasses(他们的CLSID),他们公开的接口(他们的IID),以及这些接口的方法布局,它们的参数,顺序,类型等等,我可以使用你的COM服务器。

但是为了简化COM客户端和COM服务器之间的“通信”,您可以/应该使用一些标准机制/文档并添加工具,以便像编组(=序列化)这样的管道工作将无需任何努力。这对于进程外的情况至关重要,在进程中不太重要(我将在这里躲避“公寓”概念......)

所以,你在COM中找到的很多东西(比如注册,工具,IDL,类型库等)实际上是可选的,但也非常有用(所以它们最终成为强制性的)。 idl(用于“接口语言定义”)之类的目的是为COM客户端定义和公开您的COM服务器支持的内容,因此工具可以为您和您的客户自动生成大量代码(.c,.h ,. TLB)。请注意,没有什么可以阻止您实现接口或coclass而不在idl中定义它们。没有什么要求您提供.idl或.tlb。在这种情况下,如果我知道他们的IID,方法布局等,我将只能使用它们。

然后,在IUnknown之上,Microsoft创建了一个名为IDispatch的通用接口(这也称为“自动化”,或“后期绑定”而不是IUnknown的“早期绑定”),当时针对VB / VBA客户端(之前即使是VBScript,JScript和许多其他COM客户端,.NET也支持IUnknown和IDispatch)。 IDispatch,如果你走这条路,可能是你必须实现的最后一个接口,因为它的语义允许任何方法的完全发现和调用,只要它支持一组有限的定义数据类型,“自动化类型”: BSTR,VARIANT等

所以,如果你支持IDispatch,提供TLB(typelibs)并将所有类型限制为自动化类型,那么你不需要处理编组,你不需要代理和存根,你可以忘记所有这些,即使在外面进程方案,因为Microsoft自动实现。回到过去,我们习惯称“oleaut32.dll”为“通用编组”。

双接口是同时支持IUnknown和衍生物以及IDispatch的接口。它们主要用于同时支持C / C ++客户端和自动化客户端。使用自动化(BSTR,VARIANT等)在C / C ++中有点痛苦,因为它们最初并不打算用于C / C ++客户端......注意Microsoft建议使用C ++智能包装类:CComBSTR和带有ATL的CComVARIANT,或者使用Windows SDK的_variant_t_bstr_t

另一答案

读取材料的请求超出了StackOverflow的范围,但我不得不推荐Don Box: Essential COM的开创性工作,该工作已经出版,可以在其他地方以电子书的形式提供。这是Don对该主题的描述:

盒子,唐。基本的COM。 Addison-Wesley,1998年,第350页:

COM基于客户端程序,这些客户端程序在开发时具有接口定义的先验知识。这可以通过C ++头文件(对于C ++客户端)或通过类型库(对于Java和Visual Basic客户端)来完成。通常,这不是问题,因为用这些语言编写的程序通常在部署之前经历某种编译阶段。某些语言在开发时不会经历这样的编译阶段,而是以源代码形式部署,以便在运行时进行解释。

也许最普遍的这种语言是基于html的脚本语言(例如,Visual Basic脚本,javascript),其在Web浏览器或Web服务器的上下文中执行。在这两种情况下,脚本文本都以嵌入在HTML文件中的原始形式存储,并且周围的运行时会在解析HTML时动态执行脚本文本。为了提供丰富的编程环境,这些环境允许脚本调用COM对象上的方法,这些方法可以在脚本文本本身中创建,或者可能在HTML流中的其他地方创建(例如,也是网页的一部分的控件)。在这些环境中,当前不可能使用类型库或其他先验手段来向运行时引擎提供所使用的接口的描述。这意味着对象本身必须帮助解释器将原始脚本文本转换为有意义的方法调用。

为了允许从解释环境(如Visual Basic Sc​​ript和JavaScript)中使用对象,COM定义了一个表达解释功能的接口。


Tl; dr:在COM中有两种方法可以做任何事情(忽略IInspectable和双界面):

  1. IUnknown 标准虚方法调用。快速,没有额外的代码。在客户端调用上需要编译时接口信息(.h或.tlb)
  2. IDispatch “晚结合”。慢,很多口译代码。无需客户端编译或接口规范。

实际上,除非你打电话给VBA,VBScript或者有一些旧的VB6客户端,否则你最好完全坚持使用IUnknown

以上是关于COM客户端连接COM服务器所需的文件是什么(进程外方案)?的主要内容,如果未能解决你的问题,请参考以下文章

COM 是不是提供延迟关闭直到所有 RPC 完成的方法?

什么决定了进程外COM服务器注意到客户端已经死亡的时间?

Android 逆向Android 进程注入工具开发 ( 远程进程 注入动态库 文件操作 | Android 进程读取文件所需的权限 | fopen 打开文件标志位 | 验证文件权限 )

Android 逆向Android 进程注入工具开发 ( 远程进程 注入动态库 文件操作 | Android 进程读取文件所需的权限 | fopen 打开文件标志位 | 验证文件权限 )

SmartGwt RPC 服务(com.server.GreetingServiceImpl 类型没有可用的源代码;您是不是忘记继承所需的模块?)

iOS 上自动续订订阅所需的服务器