64bit OS上でアプリを64bitモードで動作するよう「Any CPU」ビルド設定としたのに、なぜか32bitで動作する、という現象でハマったのでメモ書きです。
具体的には、Windows は 64bit OS、「Any CPU」ビルド設定のアプリで64bitのDLLを読み込み、APIを使おうとしたときに、以下の例外が発生しました。
System.BadImageFormatException: '間違ったフォーマットのプログラムを読み込もうとしました。 (HRESULT からの例外:0x8007000B)'
「Any CPU」ビルド設定とは
「Any CPU」ビルド設定は、アプリケーションが32ビット (x86) または64ビット (x64) のどちらのCPUアーキテクチャでも実行できるよう自動でアプリの動作モードを切り替えるための設定です。この設定の主な目的は、異なるプラットフォーム間でアプリケーションが柔軟に動作できるようにすること、だそうです。
困りごと
Windows 64bit OS上で、アプリを「Any CPU」ビルド設定とし、64bitのDLLを読み込み、APIを使おうとしたとき、以下の例外が発生しました。
System.BadImageFormatException: '間違ったフォーマットのプログラムを読み込もうとしました。 (HRESULT からの例外:0x8007000B)'
上記例外は、64bitアプリなのに32bitのDLLを読み込んでいた場合など、異なるプラットフォーム用のDLLを使用した場合に発生する例外です。
今回は、
- Windows は 64bit OS
- アプリは「Any CPU」ビルド設定 → 64bitモードで動いているはず
- DLLも上記に合わせて64bit版を用意
としているので、上記例外が発生するのはおかしい…と思い色々調べました。
原因と解決方法
プロジェクトのビルド設定に「32ビットを選ぶ」という項目を発見!どうやら、これがONになっていると、せっかく「Any CPU」を選択していても、64bit OS上で32bitアプリとして動作するらしい…。
この設定をOFFしたところ、アプリは64bitモードで動くようになり例外発生も解消しました!
不便に感じるのは、この設定がデフォルトでONになる点。Any CPUを選択する時点で、開発者は64bit OS上では64bitモードでアプリを動かしたいと思っているのではないでしょうか。この設定の存在理由、何なのでしょうね。
まとめ
本記事は、エラー「間違ったフォーマットのプログラムを読み込もうとしました」が発生する原因について紹介しました。「Any CPU」の設定だけでは64bitモードのアプリになりません。32ビットを選ぶのチェックボックスをOFFにするのを忘れずに。