2011-09-30 10 views
6

En C#, estoy tratando de invocar una función "simple" que tengo en C++. El problema es que no sé el nombre o la ubicación de la biblioteca en tiempo de compilación. En C++, esto es fácil:PInvocar cuando no se conoce el archivo DLL en el momento de la compilación

typedef HRESULT (*SomeFuncSig)(int, IUnknown *, IUnknown **); 

const char *lib = "someLib.dll"; // Calculated at runtime 

HMODULE mod = LoadLibrary(lib); 
SomeFuncSig func = (SomeFuncSig)GetProcAddress("MyMethod"); 

IUnknown *in = GetSomeParam(); 
IUnknown *out = NULL; 
HRESULT hr = func(12345, in, &out); 

// Leave module loaded to continue using foo. 

Porque la vida de mí no puedo encontrar la manera de hacer esto en C#. No tendría ningún problema si sabía el nombre DLL, se vería algo así:

[DllImport("someLib.dll")] 
uint MyMethod(int i, 
       [In, MarshalAs(UnmanagedType.Interface)] IUnknown input, 
       [Out, MarshalAs(UnmanagedType.Interface)] out IUnknown output); 

¿Cómo puedo hacer esto sin saber la DLL Estoy cargando desde en tiempo de compilación?

Respuesta

5

Ti es una solución aquí: Dynamically calling an unmanaged dll from .NET (C#) (basado en LoadLibrary/GetProcAddress)

+0

¿Echo de menos algo? Para usar LoadLibrary * debes * saber el nombre de la dll. Si OP _knew_ el nombre de la DLL no trataría de encontrar una solución diferente en primer lugar. Editar: creo que me perdí el "en tiempo de compilación" frente a "en tiempo de ejecución". –

7

Usted lo hace de la misma manera. Declare un tipo de delegado cuya firma coincida con la función exportada, al igual que SomeFuncSig. Pinvoke LoadLibrary y GetProcAddress para obtener el IntPtr para la función exportada, tal como lo hizo en C++. Luego crea el objeto delegado con Marshal.GetDelegateForFunctionPointer().

1

Si conoce el nombre de la DLL por adelantado, y conoce los nombres de las funciones por adelantado, hay una manera más simple.

Simplemente puede declarar las firmas P/Invocar, luego use LoadLibrary para cargar el archivo DLL según, por ejemplo, una entrada del archivo de configuración. Siempre y cuando llame con éxito al LoadLibraryantes de se utiliza cualquiera de las funciones de P/Invoke, tendrán éxito ya que la DLL ya está cargada.

Cuestiones relacionadas