これは主に展開の問題です。インストーラでターゲットマシンのWindowsバージョンに基づいて適切なDLLをコピーしてください。
しかし、誰もこれをやりたいとは思っていません。正しいDLLの関数を動的にピンポークすることは非常に苦痛です。エクスポートされた関数ごとにデリゲート型を記述し、LoadLibrary + GetProcAddress + Marshal.GetDelegateForFunctionPointerを使用してデリゲートオブジェクトを作成する必要があります。
しかし、誰もこれをやりたいとは思っていません。あまり厄介なことは、関数を2回宣言し、異なる名前を付け、[DllImport]属性のEntryPointプロパティを使って実名を指定することです。次に実行時に呼び出すテストを行います。
しかし、誰もこれをやりたいとは思っていません。最も効果的なやり方は、正しいDLLをロードするためのWindowsの操作です。まず、DLLがWindowsがそれを探していないディレクトリにコピーする必要があります。最も良い方法は、ビルドディレクトリに "x86"と "x64"サブディレクトリを作成し、それぞれに適切なDLLをコピーすることです。そうするには、ディレクトリを作成してDLLをコピーするポストビルドイベントを作成します。
次に、SetDllDirectory()をピンで指定してWindowsに通知します。指定したパスは、WindowsがDLLを検索するディレクトリに追加されます。このように:
using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.IO;
class Program {
static void Main(string[] args) {
var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
path = Path.Combine(path, IntPtr.Size == 8 ? "x64" : "x86");
bool ok = SetDllDirectory(path);
if (!ok) throw new System.ComponentModel.Win32Exception();
//etc..
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetDllDirectory(string path);
}
64ビットモードで実行するコードを実際に使用することを検討してください。唯一の本当のメリットである巨大な仮想メモリアドレス空間を必要とすることは非常にまれです。 2ギガバイトの場合でも正しく動作する必要のある32ビットバージョンをサポートする必要があります。
両方のバージョン(プライベートメソッド)をインポートしますが、環境に応じて正しいコードをクライアントコードに公開するのはどうですか? .NET 4では、[Environment.Is64BitOperatingSystem](http://msdn.microsoft。com/ja-us/library/system.environment.is64bitoperatingsystem.aspx)。注意:私は依存するネイティブDLLのために2つの異なるバージョンのC#アプリケーションを保持しません(このためにプリプロセッサは使用しません)。 –
マイケル - それはほとんど私の質問ですが、私は彼らの解決策が動作しないことを意味する1つの余分な合併症があります。私のdllはanycpuであるプロジェクトによってインポートされ、親プロジェクトはアプリケーションがx64かx86かどうかを判断します。 – Sugrue
@Sugrue次にランタイムソリューションを使う必要があります。両方をインポートし、 'Environment.Is64BitProcess'か' sizeof (void *) '、または' IntPtr.Size'です。 –