C# の HBITMAP ハンドルを使用してリモート ビットマップを取得する

StackOverflow https://stackoverflow.com/questions/3674638

  •  01-10-2019
  •  | 
  •  

質問

私は持っています 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);

これは現在のケースでは機能しません。を取得します System.Runtime.InteropServices.ExternalException 問題はそれだと思います hbitmap は、ローカル AppDomain には存在しないが、Windows サービス AppDomain には存在するメモリへのハンドルです。私の質問は、私の選択肢は何かということです。

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

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

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

役に立ちましたか?

解決

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

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

私見では。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top