Com 如何从进程外服务器为自定义编组接口实现IMarshal

Com 如何从进程外服务器为自定义编组接口实现IMarshal,com,marshalling,unmarshalling,Com,Marshalling,Unmarshalling,我试图弄清楚如何在进程外COM服务器触发事件时实现自定义封送。服务器实现IConnectionPoint接口。它调用接口上的一个方法来发出事件信号,该方法使用指向接口的指针(称为IMyEventData.)。在服务器中实现IMyEventData的类也实现IMarshal。当我的服务器触发该事件时,我会得到预期的对IMarshal的调用,包括GetMarshalSizeMax、GetUnmarshalClass和MarshalInterface。到目前为止,一切顺利 我已经在系统上注册的单独DL

我试图弄清楚如何在进程外COM服务器触发事件时实现自定义封送。服务器实现IConnectionPoint接口。它调用接口上的一个方法来发出事件信号,该方法使用指向接口的指针(称为IMyEventData.)。在服务器中实现IMyEventData的类也实现IMarshal。当我的服务器触发该事件时,我会得到预期的对IMarshal的调用,包括GetMarshalSizeMax、GetUnmarshalClass和MarshalInterface。到目前为止,一切顺利

我已经在系统上注册的单独DLL中实现了解组器。在服务器处理MarshalInterface调用之后,我的解组器DLL就会加载到客户机中,但我在其IMarshal接口上得到的调用并不是我所期望的。这些调用是对GetUnmarshalClass、GetMarshalSizeMax和MarshalInterface的调用。在所有这些调用中,上下文都在proc中,显然试图跨单元而不是进程边界封送。我从来没有接到预期的电话去解组界面。当我在调试器下运行客户机和服务器时,在调用解组器的IMarshal接口之后,输出窗口中会显示一个异常,表明发生了错误的参数错误(0x80070057)

谁能告诉我我做错了什么?我希望解组器能够调用IMarshal::UnmarshalInterface,以便访问服务器在调用IMarshal::MarshalInterface时提供的数据。我一定错过了一些基本的东西

谢谢


韦恩

这个问题有点不具体,因此答案将概述所采取的主要步骤

给定的是服务器端的接口指针,该指针需要封送到外部单元。服务器COM对象实现了应该拾取的自定义封送拆收器。客户端希望接口指针指向通过自定义封送处理获得的代理

服务器端
  • COM查询相关COM对象的
    IMarshal
    接口-这成功了,我们的对象确实实现了它
  • COM调用
    IMarshal::GetUnmarshalClass
    ,获取负责在客户端解组的类的
    CLSID
    ;这可能与服务器对象的CLSID相同,可能是代理类
    CLSID
    ,也可能是代理工厂类
    CLSID
    ——其思想是COM通过方法调用来请求,因此对象可以自由返回任何看起来合适的内容
  • COM可能会调用
    IMarshal::GetMarshalSizeMax
    为封送数据准备缓冲区
  • COM调用
    IMarshal::MarshalInterface
    来marhsal数据
客户端
  • COM从这里开始获取最终的外部请求,这表明生成代理对象和获取要提供给控制/调用方应用程序的COM接口指针需要一些技巧
  • COM拥有解组器类的CLSID和来自封送器的数据
  • COM使用
    CLSID
  • COM对创建的类调用
    imarhal::UnmarshalInterface
    ,并提供它最终想要获得的
    IID
请注意,在上面的最后一步中,COM具有以下功能:

  • 要实例化以从中请求接口指针的类的
    CLSID
  • 请求的接口指针的
    IID
  • 由于封送处理而在服务器上生成的数据

使用所有这些输入,解组器类将返回一个有效指针,该指针可能是也可能不是解组器本身的接口。因此,您可以自由选择是要一个专门的“工厂”解组器类来创建客户端对象,还是只需创建一个新实例并通过封送数据对其进行初始化。

这里应该有一些代码/详细信息。在远程端,您确实有
GetUnmarshalClass
调用,在调用中您向hanlde unmarshaling提供实际类的
CLSID
,因此基本上它是按设计进行的。您确定客户端正在创建一个进程外实例,即
CLSCTX\u INPROC\u服务器
未提供给
CoCreateInstance[Ex]