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

时间:2011-09-19 21:27:41

标签: com marshalling unmarshalling

我试图弄清楚如何在触发事件时为进程外COM服务器实现自定义编组。服务器实现IConnectionPoint接口。它调用信号事件的接口上的一个方法是一个指向接口的指针(将其称为IMyEventData。)。在服务器中实现IMyEventData的类也实现了IMarshal。当我的服务器触发事件​​时,我得到了我期望的IMarshal调用,包括GetMarshalSizeMax,GetUnmarshalClass和MarshalInterface。到目前为止,非常好。

我已在系统中注册的单独DLL中实现了unmarshaller。在服务器处理MarshalInterface调用之后,我的unmarshaller DLL被加载到客户端,但是我在其IMarshal接口上获得的调用并不是我所期望的。调用是GetUnmarshalClass,GetMarshalSizeMax和MarshalInterface。在所有这些调用中,上下文都是在进程中,显然是试图跨越公寓而不是处理边界。我从未得到对UnmarshalInterface的预期调用。当我在调试器下运行客户端和服务器时,每个在调用我的unmarshaller的IMarshal接口后立即在输出窗口中显示异常,表明发生了错误的参数错误(0x80070057)。

谁能告诉我我做错了什么?我原本以为我的unmarshaller会调用IMarshal :: UnmarshalInterface,以便能够访问服务器在调用IMarshal :: MarshalInterface时提供的数据。我必须在这里遗漏一些基本的东西。

感谢。

韦恩

1 个答案:

答案 0 :(得分:2)

问题有点不具体,所以答案将概述正在发生的主要步骤。

给定是服务器端的接口指针,指针需要编组到外部公寓。服务器COM对象实现应该拾取的自定义封送器。客户端期望接口指针指向通过自定义封送获得的代理。

服务器端

  • COM查询有问题的COM对象IMarshal接口 - 这成功了,我们的对象确实实现了它
  • COM调用IMarshal::GetUnmarshalClassCLSID负责在客户端进行解组;这可能是服务器对象的相同CLSID,这可能是代理类CLSID,或代理工厂类CLSID - 这个想法是COM通过方法调用请求它,因此对象可以自由返回任何内容似乎合适
  • COM可能会调用IMarshal::GetMarshalSizeMax来准备用于封送数据的缓冲区
  • COM致电IMarshal::MarshalInterface以传输数据

客户端

  • COM从这里开始最终获得外部请求,表明需要一些魔法来生成代理对象并获取要提供给控制/调用者应用程序的COM接口指针
  • COM拥有unmarshaler类的CLSID手和来自封送程序的数据
  • COM使用CLSID
  • 实例化一个类
  • COM在创建的类上调用IMarhsal::UnmarshalInterface并提供IID它最终想要获取

请注意,在COM的最后一步中,COM具有以下内容:

    该类的
  • CLSID实例化以从
  • 请求接口指针
  • IID请求的接口指针
  • 由于编组过程在服务器上生成的数据

对于所有这些输入,unmarshaler类应该返回一个有效的指针,该指针可能是或可能不是unmarshaler本身的接口。因此,您可以自由选择是否需要专门的“工厂”unmarshaler类来创建客户端对象,或者您只需要创建一个新实例并从编组数据中初始化它。