开发者

How to implement IMarshal for custom marshalling interface from out-of-proc server

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 impleme开发者_如何学Gonts 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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜