2010-05-12 19 views
6

Estoy utilizando una dll externa no administrada usando PInvoke y el atributo DllImport. p.ej.Establezca el atributo DllImport dinámicamente

[DllImport("mcs_apiD.dll", CharSet = CharSet.Auto)] 
private static extern byte start_api(byte pid, byte stat, byte dbg, byte ka); 

Me pregunto si es posible alterar los detalles del archivo DLL (mcs_apiD.dll en este ejemplo) dynmically de alguna manera, si, por ejemplo, que quería construir contra otra versión DLL

Respuesta

2

que pueda No cambie el nombre de la DLL, pero puede modificar la ruta de la biblioteca que se está cargando (por ejemplo, leyéndola desde el registro o un archivo de configuración) y cárguela manualmente con la función LoadLibrary kernel32: see my answer there.

+0

Ok. Pero en mi ejemplo he especificado un prototipo de función específico para que pueda ordenar los parámetros correctamente, algunas de las funciones de API tienen estructuras complejas como parámetros. ¿Cómo haría esto cuando trabaje de esta manera? – user226356

+0

si los parámetros cambian de una versión de la DLL a otra, no tiene suerte con el método que mencioné –

5

Sí, es posible que deba hacer parte del trabajo que hace el contador de visitas P/Invocar. Cargando la DLL y encontrando el punto de entrada de la función exportada. Para empezar, se declara un delegado cuya firma coincide con la función exportada:

private delegate byte start_api(byte pid, byte stat, byte dbg, byte ka); 

A continuación, utilice un código como éste:

using System.ComponentModel; 
using System.Runtime.InteropServices; 
    ... 

    static IntPtr dllHandle; 
    ... 
     if (dllHandle == IntPtr.Zero) { 
      dllHandle = LoadLibrary("mcs_apiD.dll"); 
      if (dllHandle == IntPtr.Zero) throw new Win32Exception(); 
     } 
     IntPtr addr = GetProcAddress(dllHandle, "[email protected]"); 
     if (addr == IntPtr.Zero) throw new Win32Exception(); 
     var func = (start_api)Marshal.GetDelegateForFunctionPointer(addr, typeof(start_api)); 
     var retval = func(1, 2, 3, 4); 
    ... 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr LoadLibrary(string name); 
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] 
    private static extern IntPtr GetProcAddress(IntPtr hModule, string name); 

montón de maneras de conseguir esto mal, por supuesto. Tenga en cuenta que debe usar el nombre exportado real de la DLL, ya no obtendrá la ayuda del marcador de P/Invoke para ayudar con la decoración del nombre. Use dumpbin.exe/exports en la DLL si no está seguro de cómo se ve el nombre de la exportación.

+0

de hecho, con 1 tipo de delegado por versión de la DLL API combinado con GetProcAddress, obtendrá su salida de es –

+0

Hay un artículo de blog de Microsoft sobre esto en: http://blogs.msdn.com/b/jonathanswift/archive/2006/10/03/dynamically-calling-an-unmanaged-dll-from-.net-_2800_c_23002900_ .aspx – Deanna

Cuestiones relacionadas