0

我有一个MarshalByRefObject我需要序列化和存储(在数据库中)的,所以我可以在以后反序列化和引用它。我选择了不同的方法:现在我正在运行一个 Windows 服务,它只是保持MarshalByRefObjects“活动”(请注意,RemoteObject它实际上是一个第 3 方对象,我不是自己创建的):

// 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);

在另一个 AppDomain 中,我只需连接并检索对象;一切正常:

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

现在的问题是RemoteObject包含一个属性,它只是一个HBITMAP转换为类型的句柄long。我可以轻松地取回手柄。通常(本地)我会这样做:

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

这在当前情况下不起作用。我得到一个System.Runtime.InteropServices.ExternalException我猜问题是hbitmap本地AppDomain中不存在的一些内存的句柄,但在Windows服务AppDomain中。我的问题是我的选择是什么:

  • RemoteObject是相当复杂的,它就像一棵树,您可以通过调用它的函数来遍历节点。第三方强制我只能遍历对象一次。所以在服务端遍历它,将位图存储在数据库中,然后再次远程遍历它是行不通的。
  • 理想的情况是能够调用 Windows 服务中的函数,并将 hbitmap 句柄作为参数传递,返回实际的位图。这在 Windows 服务中是不可能的。
  • 我可以将句柄存储在数据库中,并让 Windows 服务轮询数据库。然后它可以检索位图并将其存储在同一个数据库中。然后我可以再次远程检索该位图。这非常难看,因为我需要立即使用位图。

基本上我想知道你是否有建议不必像第三个选项那样执行丑陋的黑客攻击......我有什么选择?

已解决 现在我通过创建一个自定义对象来解决问题,该对象在服务端扩展 MarshalByRefObject。该对象具有通过传递句柄来检索和保存位图的方法。我只是远程接近对象,就像接近我的第 3 方对象一样。解决方案太简单了,尽管有同事不得不指出。

4

1 回答 1

1

HBitmap 是一个句柄,序列化非托管句柄是没有意义的。您需要序列化位图内容,在远程端重新创建它(位图),然后重新分配新创建的 hbitmap。

PS 物理句柄是一个指向指针的指针,它的值仅适用于创建地址空间。

恕我直言。

于 2010-09-09T08:25:08.540 回答