web-dev-qa-db-ja.com

DllImport-不正な形式のプログラムを読み込もうとしました

C#アプリケーションで条件付きでネイティブメソッドを実行したい。実行時にDLLのx86またはx64バージョンのどちらを実行するかを決定します。

この質問 コンパイル時に32ビットまたは64ビットを選択する方法を説明していますが、それは役に立ちません。実行時に決定したい。

私は現在、次のことを行っています。

[SuppressUnmanagedCodeSecurity]
internal static class MiniDumpMethods
{
    [DllImport("dbghelp.dll",
        EntryPoint = "MiniDumpWriteDump",
        CallingConvention = CallingConvention.StdCall,
        CharSet = CharSet.Unicode,
        ExactSpelling = true,
        SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool MiniDumpWriteDump(
        IntPtr hProcess,
        uint processId,
        SafeHandle hFile,
        MINIDUMP_TYPE dumpType,
        IntPtr expParam,
        IntPtr userStreamParam,
        IntPtr callbackParam);

[DllImport("dbghelpx86.dll",
EntryPoint = "MiniDumpWriteDump",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Unicode,
ExactSpelling = true,
SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool MiniDumpWriteDumpX86(
        IntPtr hProcess,
        uint processId,
        SafeHandle hFile,
        MINIDUMP_TYPE dumpType,
        IntPtr expParam,
        IntPtr userStreamParam,
        IntPtr callbackParam);
}

しかし、x86メソッドを呼び出そうとすると、エラーが発生します。

Unhandled Exception: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
   at <exeName>.MiniDumpMethods.MiniDumpWriteDumpX86(IntPtr hProcess, UInt32 processId, SafeHandle hFile, MINIDUMP_TYPE dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam)

Dllのx86またはx64バージョンを条件付きでロードする方法はありますか?

(注:dbghelpx86.dllは、私が名前を変更したdbghelp.dllのx86バージョンです)

ありがとう

6
Zain Rizvi

プログラムは、32ビットまたは64ビットのいずれかになります。 64ビットプログラムで32ビットコードを実行することはできません。また、32ビットプログラムで64ビットコードを実行することもできません。実行しようとすると、ランタイム例外が発生します。したがって、x86とx64の両方のコードを実行する1つのプログラムを持つことはできません。やりたいことに応じて、3つのオプションがあります。

オプション1 :(元の回答)

「任意のCPU」を使用すると、プログラムを32ビットプラットフォームでは32ビットとして、64ビットプラットフォームでは64ビットとして実行できます。その場合、このコードを使用して、使用するDLLを決定できます。また、32ビットと64ビットの両方のプラットフォームを処理できるようにするために必要なアセンブリは1つだけで、正しいdll:

使用する Environment.Is64BitProcess

if (Environment.Is64BitProcess)
{
   //call MiniDumpWriteDump
}
else
{
   //call MiniDumpWriteDumpX86
}

オプション2:

これを行うために「プリプロセッサ」条件を使用する場合は、2つの異なるアセンブリをコンパイルします。 32ビットアセンブリをコンパイルして32ビットDLLを使用する32ビットプラットフォームで実行し、別の64ビットアセンブリをコンパイルして64ビットプラットフォームで実行します。

オプション3:

IPC(プロセス間通信)を使用します。 32ビットプログラムに「接続」する64ビットプログラムが1つあります。 64ビットプログラムは64ビットDLL関数を実行できますが、32ビットDLL関数を実行する必要がある場合は、送信する必要があります実行に必要な情報を含むメッセージを32ビットプログラムに送信すると、32ビットプログラムは必要な情報を含む応答を送信できます。

10
LVBen