2008-08-22 10 views
16

here(アセンブリとその依存関係のロード中)と同様の問題がありますが、微妙に異なります。実行時に32ビット/ 64ビットlibsを遅くバインドする方法

3Dレンダリング用のC++ DLLは、私たちが顧客に販売するものです。 .NETユーザーの場合は、CLRラッパーを使用します。 C++ DLLは32ビットと64ビットの両方のバージョンで構築できますが、CLRが特定のDLLにバインドするので、これは2つのCLRラッパーを必要とすると思いますか?

私たちの顧客は、32ビットまたは64ビットの.NETアプリケーションを持っていますが、純粋な.NETアプリケーションであるため、CLRを残して、アセンブリの単一のセットから作業することができます。問題は、アプリケーションコードが実行時に32ビットと64ビットのCLR/DLLの組み合わせを動的に選択できることです。

もっと具体的には、上記の質問に対する回答もここにあります(つまり、ResolveEventハンドラを作成します)?

答えて

8

私はついにこれがうまくいくと答えました。

両方をコンパイルします。& 64ビットバージョン - 両方ともアンマネージド&を別々のフォルダに管理します。次に、.NETアプリケーションで実行時にアセンブリをロードするディレクトリを選択させます。

ResolveEventを使用する際の問題は、アセンブリが見つからない場合にのみ呼び出されることです。そのため、すべてが誤って32ビットバージョンで終わるのは簡単です。代わりに、2番目のAppDomainオブジェクトを使用して、ApplicationBaseプロパティを変更して正しいフォルダを指すようにします。だから、あなたは次のようなコードになります:

static void Main(String[] argv) 
    { 
    // Create a new AppDomain, but with the base directory set to either the 32-bit or 64-bit 
    // sub-directories. 

    AppDomainSetup objADS = new AppDomainSetup(); 

    System.String assemblyDir = System.IO.Path.GetDirectoryName(Application.ExecutablePath); 
    switch (System.IntPtr.Size) 
    { 
     case (4): assemblyDir += "\\win32\\"; 
      break; 
     case (8): assemblyDir += "\\x64\\"; 
      break; 
    } 

    objADS.ApplicationBase = assemblyDir; 

    // We set the PrivateBinPath to the application directory, so that we can still 
    // load the platform neutral assemblies from the app directory. 
    objADS.PrivateBinPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath); 

    AppDomain objAD = AppDomain.CreateDomain("", null, objADS); 
    if (argv.Length > 0) 
     objAD.ExecuteAssembly(argv[0]); 
    else 
     objAD.ExecuteAssembly("MyApplication.exe"); 

    AppDomain.Unload(objAD); 

    } 

最終的に2つのexes - あなたの通常のアプリとロードするビットを選択する第2の切り替えアプリケーション。 注 - 自分自身の詳細については、私は信用できません。私の同僚の一人が、私の最初のポインタを与えて、それを賞賛しました。彼がStackOverflowにサインアップしたら、私は彼に答えを割り当てます

1

似たようなシナリオが発生しました。私が使用していたツールキットは64ビット環境ではうまく動作せず、32ビットとしてバインドするようにアセンブリを動的に強制する方法を見つけることができませんでした。

アセンブリを強制的に32ビットモードで動作させることは可能ですが、これにはCLRヘッダー(フレームワーク内にあるツールがあります)にパッチを適用する必要があり、アセンブリに強く名前が付けられている場合、いい結果になる。

32ビット版と64ビット版の2種類のバイナリをビルドして公開する必要があります。

3

私は約1年前にこれを行うことができましたが、詳細のすべてを覚えていません。基本的には、IntPtr.Sizeを使用してロードするDLLを決定し、p/Invokeを通じて実際のLoadLibraryを実行できます。その時点で、あなたはメモリ内のモジュールを持っているので、その内部から関数を呼び出す/呼び出すことができなければなりません。同じモジュール名を再度読み込まないでください。

私のアプリケーションでは、実際にはC++ DLL自体がCOMサーバーとして登録されていて、生成された.NETラッパーを介してその機能にアクセスしたと思います。したがって、p /直接呼び出す。

関連する問題