misc.log

日常茶飯事とお仕事と

64bitアプリと32bit DLLの混在

意外に実験したことが無く、結構即答で答えられない質問だったのでしらべてみました。

64bit用に対象アーキテクチャをx64としてビルドされた.NETのアプリケーションから、32bit用、即ちx86用としてビルドされたアセンブリを参照して実際に動かせるのか?という実験。

サンプルプログラム

以下の構成で簡単なサンプルをVisual Studio 2010で作成しました。

  • 親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で動かすとこんな感じに。

f:id:frontline:20130704155144g:plain

また、EXEがAnyCPU、DLLがx86の場合、Windows Server 2008 Enterpriseで動かすとこんな感じ。

f:id:frontline:20130704155715g:plain


Intel Xeon Phi Coprocessor High-Performance Programming

Intel Xeon Phi Coprocessor High-Performance Programming

*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'は異なるプロセッサを対象にしています。