意外に実験したことが無く、結構即答で答えられない質問だったのでしらべてみました。
64bit用に対象アーキテクチャをx64としてビルドされた.NETのアプリケーションから、32bit用、即ちx86用としてビルドされたアセンブリを参照して実際に動かせるのか?という実験。
サンプルプログラム
以下の構成で簡単なサンプルをVisual Studio 2010のVB.NETで作成しました。
- 親EXEを作成。フォーム1つ、DLLから文字列をもらってラベルに表示。
- 文字列をPublic Sharedで公開しているだけのDLL。
- 上記DLLはプロジェクト参照でEXEプロジェクトから参照される。
このプログラムで、EXEとDLLそれぞれの「ターゲットCPU」を切り替えて動作を見てみます。
結果
こんな感じ。
呼び出し側(EXE側) | 呼ばれる側(DLL) | ビルド | 64bit OSでの動作 |
---|---|---|---|
x86 | x86 | 成功 | 正常動作 |
x86 | x64 | 警告*1 | エラー*2 |
x86 | AnyCPU | 成功 | 正常動作 |
x64 | x86 | 成功 | エラー |
x64 | x64 | 成功 | 正常動作 |
x64 | AnyCPU | 警告*3 | 正常動作 |
AnyCPU | x86 | 成功 | エラー |
AnyCPU | x64 | 警告*4 | 正常動作 |
AnyCPU | AnyCPU | 成功 | 正常動作 |
とりあえず、明確に64ビットと宣言しているものが、明確に32ビットと宣言しているものを参照した場合、ビルドは通るけれど動かない、ということで。
また、AnyCPUを実行形式のプログラム(拡張子がEXEのもの)に設定した場合、動作するOSが32ビットか64ビットかによって、そのプログラム自体が動くプラットフォームが決定されるのですね。なので、64ビットOSでAnyCPUのプログラムを動かすと、まず「64bitアプリとして」動き始める。しかし、DLLがx86でビルドされていると、呼び元の64bitとDLLの32bitで不一致が起きて動作しない。そゆこと。
実際に発生したエラー
EXEがx86、DLLがx64の場合、Windows Server 2008 Enterpriseで動かすとこんな感じに。
また、EXEがAnyCPU、DLLがx86の場合、Windows Server 2008 Enterpriseで動かすとこんな感じ。
Intel Xeon Phi Coprocessor High Performance Programming
- 作者: James Jeffers,James Reinders
- 出版社/メーカー: Morgan Kaufmann
- 発売日: 2013/02/15
- メディア: ペーパーバック
- この商品を含むブログを見る
*1:警告は3件。後述の「mscorlib.dll」「System.Data.dll」に加え、参照している自作DLLも「異なるプロセッサを対象にしています。」メッセージが表示された。
*2:発生したエラー: APPCRASH。
*3:警告はは2件で、対象アセンブリは「msdcorlib.dll」と「System.Data.dll」。メッセージは…… アセンブリ~をビルド中に問題が発生した可能性があります:参照アセンブリ'mscorlib.dll'は異なるプロセッサを対象にしています。
*4:警告はは2件で、対象アセンブリは「msdcorlib.dll」と「System.Data.dll」。メッセージは…… アセンブリ~をビルド中に問題が発生した可能性があります:参照アセンブリ'mscorlib.dll'は異なるプロセッサを対象にしています。