0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C#】「間違ったフォーマットのプログラムを読み込もうとしました」(BadImageFormatException) の原因と解決方法

0
Posted at

BadImageFormatException_1.jpg

結論(先に解決方法)

プロジェクトのプロパティ > ビルド > 全般「32ビットを選ぶ」のチェックを外す とエラーが解消されるパターンが多いです。

BadImageFormatException_4.jpg

エラーの正体

C#でライブラリ(DLL)を使ったプログラムを実行すると、以下のようなエラーが出ることがあります。

System.BadImageFormatException: 間違ったフォーマットのプログラムを読み込もうとしました。

「間違ったフォーマットのプログラムを読み込もうとしました。」という表現はマイクロソフトらしく何を言っているのか分かりづらいですが、これは ビット数の不一致 が原因です。

具体的には、以下のどちらかの状況で発生します。

  • 32ビット で動作しているプログラムから 64ビット のDLLを読み込もうとした
  • 64ビット で動作しているプログラムから 32ビット のDLLを読み込もうとした

つまり、プログラムとDLLのビット数が合っていないときに出るエラーです。

DLLには2種類ある

ライブラリ(DLL)には大きく分けて 2種類 あります。

C#で作成されたDLL(マネージDLL)

  • C#から 直接参照 して使えます
  • AnyCPU で作成されることが多く、呼び出し元のプログラムのビット数に合わせて32ビットでも64ビットでも動作します
  • C#だけで作成されたDLLを使っている分には、ビット数の問題は 起きません

C言語(C++)で作成されたDLL(ネイティブDLL)

  • C#からは DllImport を使った関数定義で使用します
  • AnyCPUの設定がない ため、32ビットか64ビットのどちらかで作成されています
  • 今どきは 64ビット で作成されていることが多いです
// C言語のDLLをC#から使う場合のDllImportの例
[DllImport("NativeLibrary.dll")]
static extern int SomeFunction(int param);
比較項目 C# DLL(マネージDLL) C/C++ DLL(ネイティブDLL)
C#からの使い方 参照の追加(直接) DllImport(P/Invoke)
AnyCPU対応 対応 非対応
ビット幅 呼び出し元に合わせる(32/64) ビルド時に固定(32 or 64)
現在の主流 AnyCPU 64ビット
ミスマッチリスク 低い 高い

なぜエラーが起きるのか?

問題は、C#のDLLが内部でC言語のDLLを使っている場合 です。

ハードウェアを制御するライブラリや、高速な処理を行うライブラリは、表向きはC#のDLLを参照してプログラムを作成しているように見えますが、実際には C#のDLL(AnyCPU)がC言語のDLL(64ビット)を呼んでいる 場合が多いです。

この場合、以下のような呼び出しの流れになります。

エラーが起きるパターン

あなたのアプリ(32ビット)
  → C#のDLL(AnyCPU → 32ビットとして動作)
    → C言語のDLL(64ビット)
      → ビット数が合わない!エラー!

C#のDLL自体はAnyCPUなので、呼び出し元のアプリが32ビットなら32ビットとして動作します。しかし、その先で呼んでいるC言語のDLLは64ビット固定です。32ビットのプロセスから64ビットのDLLは読み込めない ため、エラーが発生します。

エラーが起きないパターン

あなたのアプリ(64ビット)
  → C#のDLL(AnyCPU → 64ビットとして動作)
    → C言語のDLL(64ビット)
      → ビット数が一致!正常動作!

罠:新規プロジェクトはデフォルトで32ビット動作

ここが一番のハマりポイントです。

Visual Studioで新規にプロジェクトを作成すると、プラットフォームターゲットは AnyCPU に設定されます。「AnyCPUなら64ビットOSでは64ビットで動くのでは?」と思いがちですが、違います

新規プロジェクトでは 「32ビットを選ぶ」(Prefer 32-bit)にデフォルトでチェックが入っている ため、AnyCPUと書いてあっても 実際には32ビットで動作 してしまいます。

Windows 11時代では32ビットOSはもう存在しないのに、最新のVisual Studio 2026であっても「32ビットを選ぶ」がデフォルトで有効になっているため、何も意識しないと32ビットで動作するプログラムを作成してしまうのです。

解決方法

手順

  1. Visual Studioで プロジェクトのプロパティ を開く(プロジェクトを右クリック → プロパティ)
  2. ビルド > 全般 を選択
  3. 「32ビットを選ぶ」(Prefer 32-bit)のチェックを外す
  4. プロジェクトをリビルドして実行

BadImageFormatException_4.jpg

別の解決方法:プラットフォームをx64に変更

「32ビットを選ぶ」を外す代わりに、プラットフォームターゲット自体を x64 に変更する方法もあります。

  1. プロジェクトのプロパティ → ビルド → 全般
  2. プラットフォームターゲットを AnyCPU から x64 に変更

こちらの方が明示的で分かりやすいですが、32ビット環境では動作しなくなります(現在のWindows 11では問題ありません)。

まとめ

項目 内容
エラーの意味 プログラムとDLLのビット数が合っていない
主な原因 32ビットで動作するアプリから64ビットのDLLを呼んでいる
なぜハマるか 新規プロジェクトはデフォルトで「32ビットを選ぶ」が有効
解決方法 プロジェクトのプロパティ > ビルド > 全般 で「32ビットを選ぶ」のチェックを外す

特に、C#のDLLが内部でC言語(C++)のネイティブDLLを使っている場合にこのエラーが起きやすいです。ハードウェア制御系や画像処理系のライブラリを使う際は、真っ先にこの設定を確認してみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?