0

最近までサービスを x86 として実行していましたが、Any CPU に変更して、64 ビット DLL を使用したいくつかの新しい機能を導入しました。サード パーティの DLL の残りの 1 つが 32 ビットでした。そのための DLL サロゲートをレジストリにセットアップしましたが、それは解決策の半分にすぎません。

inProc で実行されなくなったため、メモリ内に作成されているポインターにアクセスできないと思われます。私が知る必要があるのは、System.Runtime.InteropServices.Marshall オブジェクトを使用して、返されたポインターにアクセスする方法です。

前もって感謝します。

public Image GetThumbnail(string strFilename)
    {
        SeThumbnailExtractor objExtractor = new SeThumbnailExtractor();
        int hImageSE;
        Image objImage = null;
        try
        {
            objExtractor.GetThumbnail(strFilename, out hImageSE);
            IntPtr iPImage = new IntPtr(hImageSE);
            //fails below
            objImage = Image.FromHbitmap(iPImage);
            _ReturnedImage = objImage;
            _SourceFile = strFilename;
            Marshal.FreeHGlobal(iPImage);
        }
        catch (Exception ex)
        {
            _ErrorMsg = "ERROR: " + ex.Message.ToString();
        }

        if (objExtractor != null)
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(objExtractor);
            objExtractor = null;
        }

        return objImage;
    }
4

1 に答える 1

2

サロゲートでの実行は、適切に実装された COM コンポーネントに対して完全に透過的です。コンポーネントのプロキシ/スタブは、インターフェイス メソッドの引数と戻り値がプロキシによって相互運用データ パケットに適切にシリアル化されることを保証します。これにより、プロセス分割を介して送信され、スタブで再度逆シリアル化されます。

ただし、「適切に実装されている」ことは問題です。COM メソッドから未加工のビットマップ ハンドルまたはポインタを取得すると、問題が発生します。ハンドルまたはポインターはシリアル化できません。それを作成したプロセスでのみ有効です。そのハンドルを実際のビットマップ データに置き換え、そのデータをスタブに送信して、64 ビット プロセスで新しいハンドル/ポインタを使用してビットマップを再作成できるようにするカスタム プロキシ/スタブが必要です。

COM コンポーネントの作成者がそれを処理した可能性は低く、実行するのは簡単ではありません。また、コンポーネントが常にインプロセスで使用されると想定していたため、その時点で要件を認識していなかったに違いありません。それはもうありません。

これを簡単に修正する方法はありません。適切なプロキシ/スタブを作成する必要があり、少なくともコンポーネントの元の IDL にアクセスできる必要があります。通常、COM 作成者のみがアクセスできます。悪いニュースですね。

考えられる回避策は、.NET に処理を任せることです。COM コンポーネントを問題なくロードできるように、32 ビット モードで実行される小さなヘルパー プロセスが必要になります。WCF や Remoting などの .NET 相互運用メカニズムのいずれかを使用して対話します。ビットマップをシリアライズすることは、完全にあなたの手の中にあります。

于 2013-10-10T13:04:18.623 に答える