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

投稿者: | 2017/10/13 金曜日

普通に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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です