2011-09-30 6 views
6

In C#, sto provando a PInvoke una funzione "semplice" che ho in C++. Il problema è che non conosco il nome o la posizione della libreria in fase di compilazione. In C++, questo è facile:PInvoke quando non si conosce la DLL al momento della compilazione?

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. 

Per la vita di me non riesco a capire come fare questo in C#. Non avrei alcun problema se sapessi il nome dll, sarebbe risultato qualcosa come questo:

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

Come posso fare questo senza conoscere il dll sto caricando da al momento della compilazione?

risposta

5

Te è una soluzione qui: Dynamically calling an unmanaged dll from .NET (C#) (sulla base di LoadLibrary/GetProcAddress)

+0

Mi manca qualcosa? Per utilizzare LoadLibrary è necessario * conoscere * il nome della DLL. Se l'OP _knew_ il nome della DLL non tenterebbe di trovare una soluzione diversa in primo luogo. Modifica: penso di aver perso "in fase di compilazione" rispetto a "in fase di esecuzione". –

7

Lo si fa nello stesso modo. Dichiarare un tipo di delegato la cui firma corrisponde alla funzione esportata, proprio come SomeFuncSig. Pinvoke LoadLibrary e GetProcAddress per ottenere IntPtr per la funzione esportata, proprio come hai fatto in C++. Quindi creare l'oggetto delegato con Marshal.GetDelegateForFunctionPointer().

1

Se si conosce il nome della DLL in anticipo e si conoscono i nomi delle funzioni in anticipo, esiste un modo più semplice.

È possibile dichiarare semplicemente le firme P/Invoke, quindi utilizzare LoadLibrary per caricare la DLL in base, ad esempio, a una voce di file di configurazione. Finché si chiama con successo LoadLibraryprima di, si utilizza una qualsiasi delle funzioni P/Invoke, esse avranno esito positivo poiché la DLL è già stata caricata.