Jest to przede wszystkim problem rozmieszczenia, po prostu instalator skopiować właściwej DLL oparte na wersji systemu Windows na komputerze docelowym.
Ale nikt nigdy nie lubi tego robić. Dynamiczne przypinanie poprawnej funkcji DLL jest ogromnie bolesne, musisz napisać typy delegatów dla każdej wyeksportowanej funkcji i użyć LoadLibrary + GetProcAddress + Marshal.GetDelegateForFunctionPointer do utworzenia obiektu delegata.
Ale nikt nigdy nie lubi tego robić. Mniej bolesne podejście polega na dwukrotnym zadeklarowaniu funkcji, nadaniu jej różnych nazw i użyciu właściwości EntryPoint w atrybucie [DllImport] w celu określenia prawdziwej nazwy. Następnie przetestuj w czasie wykonywania, do którego chcesz zadzwonić.
Ale nikt nigdy nie lubi tego robić. Najskuteczniejszą sztuczką jest nakierowanie systemu Windows na ładowanie poprawnej biblioteki DLL dla ciebie. Pierwszą rzeczą, którą musisz zrobić, to skopiować bibliotekę DLL do katalogu, w którym system Windows jej nie szuka. Najlepszym sposobem jest utworzenie podkatalogu "x86" i "x64" w katalogu budowy i skopiowanie odpowiedniej biblioteki DLL do każdego z nich. Zrób to, pisząc zdarzenie post-build, które tworzy katalogi i kopie bibliotek DLL.
Następnie powiedz o tym systemowi Windows, wyszukując SetDllDirectory(). Podana ścieżka zostanie dodana do katalogów, w których system Windows szuka biblioteki DLL. Tak:
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);
}
Czy rozważyć, czy mając bieg kodu w trybie 64-bitowym jest rzeczywiście przydatna. Rzadko zdarza się, że potrzebna jest gigantyczna przestrzeń adresowa pamięci wirtualnej, którą można uzyskać, jedyną realną korzyścią. Nadal musisz obsługiwać wersję 32-bitową, która musi działać poprawnie w przypadku 2 gigabajtów.
Co zrobić, aby zaimportować OBU wersje (prywatne metody), ale wystawiać na kod klienta prawo w zależności od środowiska? W .NET 4 po prostu sprawdź [Environment.Is64BitOperatingSystem] (http://msdn.microsoft.com/en-us/library/system.environment.is64bitoperatingsystem.aspx). Uwaga: Nie zachowałbym dwóch różnych wersji aplikacji C# ze względu na zależną natywną bibliotekę DLL (więc nie używałbym do tego preprocesora). –
Michael - to prawie moje pytanie, ale mam jedną dodatkową komplikację, która oznacza, że ich rozwiązanie nie zadziała. Moja biblioteka dll jest importowana przez projekt, który jest anycpu, a projekt nadrzędny decyduje, czy aplikacja jest x64 czy x86 – Sugrue
@Sugrue Następnie będziesz musiał użyć rozwiązania runtime, a mianowicie zaimportuj oba i użyj 'Environment.Is64BitProcess' lub' sizeof (void *) 'lub' IntPtr.Size'. –