AnyCPUのアセンブリから自動でx86かx64のアセンブリをロードする

普通にC#でアプリケーションを作るとAnyCPUのアセンブリができる。これは64ビット環境では64ビットで動作し、32ビットの場合は32ビットで動作する。

C++やC++/CLIで作ったライブラリはAnyCPUにすることができない。そしてWindowsでは64ビットアプリは64ビットのライブラリしかロードできない。32ビットも同じ。

AnyCPUのアプリをつくるときにこの問題をどう解決するかのはなし。ここではC++/CLIでライブラリをつくり、それをC#から利用することを考える。

C++/CLIで32ビットと64ビットのライブラリをつくる

作り方は省略。MyLib.x86.dllとMyLib.x64.dllができたとする。

C#でMyLib.x86.dllを参照する

参照するときに、プロジェクトの参照をするのではなく、ファイルを直接参照する。参照のプロパティのCopy LocalをFalseにする。こうすることでビルド時にライブラリがコピーされない。

C#のビルドイベントでMyLib.*をターゲットディレクトリにコピーする

この時のコピー先のパスはランタイムが自動で見つけられない場所にする。自動で見つけると違うdllをロードして例外が発生する。

以下はビルド後のコマンドの例、アプリのフォルダ配下のplatformにコピーしている。

この状態でアプリを起動してもライブラリが見つからない、のエラーが出る。

staticコンストラクタでカスタムローダを設定する

staticコンストラクタはstatic main()よりも早く動く。ここでライブラリが見つからないときのイベントハンドラを設定し、ハンドラで適切なライブラリを読み込む。以下はC#でデフォルトでできるクラスProgramに記述する例。

もともとx86の方を参照しているので、ランタイムはこのファイルがないと通知してくる。ここで環境(Environment.Is64BitProcess)に合わせてライブラリを読み込む。

参照

Using Side-by-Side assemblies to load the x64 or x32 version of a DLL

Leave a Reply

Your email address will not be published. Required fields are marked *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)