0

シリアル化して(データベースに)保存する必要があるMarshalByRefObjectものがあるので、後で逆シリアル化して参照することができます。私はこれに別の方法でアプローチすることを選択しました。現在、単に「生きている」状態を維持するWindowsサービスを実行しています(これは実際にはサードパーティのオブジェクトであり、自分で作成したものではないことにMarshalByRefObjects注意してください)。RemoteObject

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

現在の場合、これは機能しません。問題は、ローカルのAppDomainには存在しないが、WindowsサービスのAppDomainには存在しないメモリへのハンドルであるSystem.Runtime.InteropServices.ExternalExceptionと思います。hbitmap私の質問は私のオプションが何であるかです:

  • これRemoteObjectはかなり複雑で、関数を呼び出してノードをトラバースするツリーのようなものです。サードパーティは、オブジェクトを1回しかトラバースできないことを強制します。したがって、サービス側でトラバースし、データベースにビットマップを格納し、リモートで再度トラバースすることは機能しません。
  • 理想的なのは、Windowsサービスで関数を呼び出し、hbitmapハンドルを引数として渡して、実際のビットマップを返すことができることです。これは、Windowsサービスでは不可能です。
  • ハンドルをデータベースに保存し、Windowsサービスでデータベースをポーリングすることができます。次に、ビットマップを取得して、同じDBに保存できます。その後、そのビットマップをリモートで再度取得できます。ビットマップがすぐに必要なので、これは非常に醜いです。

基本的に、3番目のオプションのような醜いハックを実行する必要がないという提案があるかどうか知りたいです...私のオプションは何ですか?

解決済み現在、サービス側でMarshalByRefObjectを拡張するカスタムオブジェクトを作成することで問題を解決しましたこのオブジェクトには、ハンドルを渡すことによってビットマップを取得して保存するメソッドがあります。サードパーティのオブジェクトにアプローチするのと同じ方法で、オブジェクトにリモートでアプローチするだけです。同僚がそれを指摘しなければならなかったが、解決策は単純すぎる。

4

1 に答える 1

1

HBitmapはハンドルであり、管理されていないハンドルをシリアル化する意味はありません。ビットマップコンテンツをシリアル化し、リモート側で再作成(ビットマップ)してから、新しく作成したhbitmapを再割り当てする必要があります。

PS物理的にハンドルはポインタへのポインタであり、その値はアドレス空間が作成された場合にのみ適用されます。

私見では。

于 2010-09-09T08:25:08.540 に答える