Sì, questo è possibile, devi fare parte del lavoro che fa il marshaller P/Invoke. Caricamento della DLL e ricerca del punto di ingresso della funzione esportata. Inizia dichiarando un delegato la cui firma corrisponde la funzione esportata:
private delegate byte start_api(byte pid, byte stat, byte dbg, byte ka);
Quindi utilizzare il codice come questo:
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);
Un sacco di modi per ottenere questo torto, naturalmente. Si noti che è necessario utilizzare il nome esportato effettivo dalla DLL, non si ottiene più l'aiuto dal marshaller P/Invoke per aiutare con la decorazione del nome. Utilizzare dumpbin.exe/exports nella DLL se non si è certi del nome dell'esportazione.
fonte
2010-05-12 12:58:35
Ok. Ma nel mio esempio ho specificato un prototipo di funzione specifica in modo da poter eseguire correttamente il marshalling dei parametri, alcune delle funzioni api hanno strutture complesse come parametri. Come dovrei farlo quando lavoro in questo modo? – user226356
se i parametri cambiano da una versione della DLL a un'altra, sei sfortunato con il metodo che ho citato –