Question

I have a MarshalByRefObject which I needed to serialize and store (in a database), so I could deserialize and reference it later. I have chosen to approach this differently: right now I am running a Windows Service which simply keeps the MarshalByRefObjects "alive" (please note that the RemoteObject is actually a 3rd party object, which I do not create myself):

// This is the object which extends the MarshalByRefObject class
RemoteObject myRemoteObject = new RemoteObject;

TcpServerChannel channel = new TcpServerChannel(6789);
ChannelServices.RegisterChannel(channel, true);

ObjRef objRef = RemotingServices.Marshal((System.MarshalByRefObject)myRemoteObject, id);

In another AppDomain I simply connect and retrieve the object; all works fine:

RemoteObject myLocalObject = (FCEngine.IFCVerificationSession)Activator.GetObject(
                           typeof(FCEngine.IFCVerificationSession),"tcp://localhost:6789/" + id);

Now the problem is that the RemoteObject contains a property which is simply an HBITMAP handle casted to the long type. I can retrieve the handle easily. Normally (locally) I would do:

IntPtr hbitmap = (IntPtr)myLocalObject.ContextImage;
System.Drawing.Bitmap bmp = System.Drawing.Image.FromHbitmap(hbitmap);

This doesn't work in the current case. I get a System.Runtime.InteropServices.ExternalException I guess the problem is that hbitmap is a handle to some memory which doesn't exist in the local AppDomain, but in the Windows Service AppDomain. My question is what my options are:

  • The RemoteObject is pretty complex, it's like a tree in which you traverse the nodes by calling its functions. The 3rd party imposes that I can only traverse the object once. So traversing it Service-side, storing bitmaps in a database, and traversing it remotely again won't work.
  • Ideal would be to be able to call a function in the Windows Service, and pass the hbitmap handle as an argument, returning the actual bitmap. This is not possible in Windows Services.
  • I could store the handle in a database and make the Windows Service poll the database for it. It could then retrieve the bitmap and store it in that same DB for me. I could then again retrieve that bitmap remotely. This is very ugly, since I need the bitmap immediately.

Basically I'd like to know if you have suggestions to not have to perform ugly hacks like the 3rd option...What are my options?

SOLVED Right now I solved the problem by creating a custom object which extends MarshalByRefObject on the service side. This object has a method to retrieve and save a bitmap by passing the handle. I simply approach the object remotely, in the same way I approach my 3rd party object. Too simple of a solution, although a colleague had to point it out.

Was it helpful?

Solution

HBitmap is a handle, it has no sense to serialize unmanaged handles. You need to serialize the bitmap content, recreate it (bitmap) on a remote side, and then re-assign newly created hbitmap.

P.S. Physically handle is a pointer to pointer, its value is applicable only an the address space is was created.

IMHO.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top