C#&32bitアンマネージDLL/64bitアンマネージDLLの動的な呼び出し方法

Windows7の登場で
64ビット環境が,すさまじい勢いで普及しておりますです...

して,Windowsの32ビットアプリ,64ビットアプリには掟がありまして

32ビットのEXEは,32ビットのDLL
64ビットのEXEは,64ビットのDLL

しか,呼べないことになっております.交差して呼び出すことは現状,仕様で出来ません

そこで,登場する,C#で作ったアプリ(マネージアプリ)
C#やら,VB.NETやらで作成したアプリは,インストールした環境にて,JITコンパイラが,最終コンパイルしてくれます

Windowsが32ビットだったら,32ビットアプリに
Windowsが64ビットだったら,64ビットアプリに

コンパイルします

ただ,最終コンパイルしたEXEが,アンマネージ(VCあたりで作った)なDLLを呼んでいる場合は,問題が生じますです

マネージ側が64ビットにJITコンパイルしてくれても,アンマネージDLLは32ビットのまま
上の方に書いた法則が発動して,BadImageFormatExceptionなエラーが発生となります

ってことで,環境に依存せず,BadImageFormatExceptionエラーを出さないような,Exe~DLLの呼び出し方法をちょいと書いてみました



1.まずは,32ビットと64ビットのDLLをVC++で作成しましょう

MSDNに64ビットなアプリの作り方が書いてあります

作成したDLLは,
    32ビット:hogehoge.dll
    64ビット:hogehoge64.dll
と,DLLの名称を変えておきます

VC++のコードは,32/64ビットでコード変更はないはずです

2.C#(あるいはVB.NET)でDLLを呼び出すコードを書きます
こんな感じ
#region 32bitDLL のAPI定義
[DllImport("hogehoge.dll", EntryPoint="dll_TestFunc")]
private static extern int dll_TestFunc32(int frameno, IntPtr ary, int aryCount);
#endregion

#region 64bitDLL のAPI定義
[DllImport("hogehoge64.dll", EntryPoint="dll_TestFunc")]
private static extern int dll_TestFunc64(int frameno, IntPtr ary, int aryCount);
#endregion

public int TestFunc(int frameno, ref float[] ary)
{
	int len = ary.Length;
	GCHandle gcH = GCHandle.Alloc(ary, GCHandleType.Pinned);
	int re;

    if (IntPtr.Size == 4)		//IntPtrのサイズで 32ビット環境か64ビット環境か調べる
    {
		re = dll_TestFunc32(frameno,	gcH.AddrOfPinnedObject(), len);		//32ビットのDLL呼び出し
	}
	else
	{
		re = dll_TestFunc64(frameno,	gcH.AddrOfPinnedObject(), len);		//64ビットのDLL呼び出し
	}

	gcH.Free();
	return re;
}
DllImport命令のEntryPoint属性を使用し
32ビットDLL/64ビットDLLで,同一API名を別名付けて管理します

また,IntPtrのサイズを見て,現在の実行環境が32ビット/64ビットなのか,判断して
別名つけたAPIを呼び出します

3.(2)で作ったマネージなExeと同一フォルダに,この2つのDLLを置きます

こんな感じ
//  host.exe(C#で作ったマネージなExe)
//      |
//      +--- hogehoge.dll(VC++で作ったアンマネージな32ビットDLL)
//      |
//      +--- hogehoge64.dll(VC++で作ったアンマネージな64ビットDLL)
32ビットWindows
64ビットWindows

どっちの環境に,このまんま,コピペしても問題なく動くはずです


これで,32ビット/64ビット過渡期時代も生き残れますわん 😉

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください