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

发布于 2024-12-05 07:21:50 字数 746 浏览 1 评论 0原文

我试图弄清楚如何在进程外 COM 服务器触发事件​​时实现自定义编组。服务器实现 IConnectionPoint 接口。它调用以发出事件信号的接口上的方法之一采用指向接口的指针(将其称为 IMyEventData。)。服务器中实现 IMyEventData 的类也实现 IMarshal。当我的服务器触发该事件时,我会收到预期的 IMarshal 调用,包括 GetMarshalSizeMax、GetUnmarshalClass 和 MarshalInterface。到目前为止,一切都很好。

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

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

谢谢。

韦恩

I am trying to figure out how to implement custom marshalling for an out-of-proc COM server when it fires an event. The server implements the IConnectionPoint interface. One of the methods on the interface that it calls to signal an event takes a pointer to an interface (Call it IMyEventData.). The class that implements IMyEventData in the server also implements IMarshal. When my server fires the event, I get the calls to IMarshal that I expect, including GetMarshalSizeMax, GetUnmarshalClass, and MarshalInterface. So far, so good.

I have implemented the unmarshaller in a separate DLL that is registered on the system. Right after the server handles the MarshalInterface call, my unmarshaller DLL gets loaded into the client, but the calls that I get on its IMarshal interface are not what I expect. The calls are to GetUnmarshalClass, GetMarshalSizeMax, and MarshalInterface. In all of these calls, the context is in-proc, apparently attempting to marshal across apartments rather than process boundaries. I never get the expected call to UnmarshalInterface. When I run both client and server under the debugger, each displays an exception in the output window right after the calls to my unmarshaller's IMarshal interface are made, indicating that an incorrect parameter error (0x80070057) occurred.

Can anyone tell me what I am doing wrong? I had expected my unmarshaller to get a call to IMarshal::UnmarshalInterface so that it would get access to the data that the server supplied in the call to IMarshal::MarshalInterface. I must be missing something basic here.

Thanks.

Wayne

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叹梦 2024-12-12 07:21:50

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

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

服务器端

  • COM 查询相关 COM 对象的 IMarshal 接口 - 这成功了,我们的对象确实实现了它
  • COM 调用 IMarshal::GetUnmarshalClass 来获取 CLSID > 负责客户端解组的类;这可能与服务器对象的 CLSID 相同,这可能是代理类 CLSID 或代理工厂类 CLSID - 这个想法是 COM 通过方法调用请求它,所以对象可以自由地返回任何看起来合适的内容
  • COM 可能会调用 IMarshal::GetMarshalSizeMax 来准备用于封送数据的缓冲区
  • COM 调用 IMarshal::MarshalInterface marhsal 数据

客户端

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

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

  • 要实例化的类的 CLSID,以从
  • 请求接口指针所请求的接口指针的 IID
  • 作为编组过程的结果在服务器上生成的数据

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

The question is a bit not specific, so the answer will outline the main steps taking place.

Given is an interface pointer on the server side and the pointer needs to get marshaled into foreign apartment. The server COM object implements custom marshaler supposed to be picked up. The client expects the interface pointer to a proxy obtained through custom marshaling.

Server Side

  • COM queries the COM object in question for IMarshal interface - this succeeds, our object indeed implements it
  • COM calls IMarshal::GetUnmarshalClass to get CLSID of the class responsible for unmarshaling on client side; this might be the same CLSID of the server object , this could be proxy class CLSID, or proxy factory class CLSID - the idea is that COM requests this via method call, so object is free to return whatever seems appropriate
  • COM might call IMarshal::GetMarshalSizeMax to prepare a buffer for marshaling data
  • COM calls IMarshal::MarshalInterface to marhsal the data

Client Side

  • COM starts here getting eventually external request suggesting that some magic is necessary to spawn a proxy object and obtain COM interface pointer to be given to the controlling/caller application
  • COM has on hands CLSID of the unmarshaler class and data from the marshaler
  • COM instantiates a class using the CLSID
  • COM calls IMarhsal::UnmarshalInterface on the created class and provides IID it eventually wants to obtain

Note that on the last step above COM has the following:

  • CLSID of the class to instantiate to request interface pointer from
  • IID of the interface pointer requested
  • Data produced on server as a result of marshaling process

With all these inputs, the unmarshaler class is expected to return a valid pointer, which might be or might be not the interface of the unmarshaler itself. So you are free to choose whether you want a specialized "factory" unmarshaler class to do create client side object, or you want simply create a new instance and initialize it from marshaling data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文