Esto es principalmente un problema de implementación, solo haga que su instalador copie la DLL correcta según la versión de Windows en la máquina de destino.
Pero a nadie le gusta hacer eso. Pinkear dinámicamente la función correcta de la DLL es enormemente dolorosa, debe escribir tipos de delegados para cada función exportada y usar LoadLibrary + GetProcAddress + Marshal.GetDelegateForFunctionPointer para crear el objeto delegado.
Pero a nadie le gusta hacer eso. La táctica menos dolorosa es declarar la función dos veces, darle diferentes nombres y usar la propiedad EntryPoint en el atributo [DllImport] para especificar el nombre real. Luego prueba en el tiempo de ejecución al que deseas llamar.
Pero a nadie le gusta hacer eso. El truco más efectivo es orientar a Windows para que cargue la DLL correcta por usted. Lo primero que debe hacer es copiar el archivo DLL en un directorio donde Windows no lo busque. La mejor manera es crear un subdirectorio "x86" y un "x64" en su directorio de compilación y copiar el DLL apropiado en cada uno. Hágalo escribiendo un evento de creación posterior que cree los directorios y copie los archivos DLL.
Luego cuéntele a Windows al respecto pinvoking SetDllDirectory(). La ruta que especifique se agregará a los directorios que Windows busca para una DLL. De esta manera:
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);
}
Considere si el hecho de tener el código ejecutado en modo de 64 bits es realmente útil para usted. Es bastante raro que necesite el espacio de direcciones de memoria virtual gigante que obtiene de él, el único beneficio real. Aún necesita admitir la versión de 32 bits que necesita funcionar correctamente en el caso de 2 gigabytes.
¿Qué hay para importar AMBAS versiones (métodos privados) pero exponer al código del cliente el correcto según el entorno? Con .NET 4, simplemente marque [Environment.Is64BitOperatingSystem] (http://msdn.microsoft.com/en-us/library/system.environment.is64bitoperatingsystem.aspx). Tenga en cuenta que no mantendría dos versiones diferentes de la aplicación C# debido a la DLL nativa dependiente (por lo que no usaría el preprocesador para esto). –
Michael: esa es casi mi pregunta, pero tengo una complicación adicional que significa que su solución no funcionará. Mi dll es importado por un proyecto que es anycpu, y un proyecto principal decide si la aplicación es x64 o x86 – Sugrue
@Sugrue Luego tendrá que usar una solución de tiempo de ejecución, es decir, importar ambas y usar 'Environment.Is64BitProcess', o' sizeof (void *) ', o' IntPtr.Size'. –