Chiamata di un tipo personalizzato da una DLL scritta in C ++ da C #
-
18-09-2019 - |
Domanda
Io sto usando una DLL scritta in C ++ nel mio progetto C #. Sono stato in grado di chiamare funzioni all'interno della DLL utilizzando questo codice:
[DllImport("hidfuncs", EntryPoint = "vm_hid_scan", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr VmHidScan();
Ora ho bisogno di chiamare una funzione che requres un puntatore tipo personalizzato. Il Docs per la DLL Layout La funzione come questa:
hid_get_info(int n,PDEV_INFO *pdi)
Non so come usare questo puntatore personalizzato. E 'questo definito nella DLL? Se sì, come può essere utilizzato da C # progetto? Se non devo includere il file di intestazione in C #? Grazie in anticipo per il vostro aiuto.
Soluzione
Dato il prefisso "P", sembra che la vera e propria dichiarazione è
hid_get_info(int n, DEV_INFO **pdi)
dove DEV_INFO è una struttura. Avrete bisogno di trovare la dichiarazione di questa struttura e aggiungerlo al tuo codice C # con l'attributo [StructLayout]. Farebbe quindi dichiarare la funzione come questo nel tuo codice C #:
[DllImport("blah.dll")]
private static extern something hid_get_info(int n, out IntPtr pdi);
Utilizzando Marshal.PtrToStructure () per ottenere il valore della struttura. Speriamo che non c'è bisogno di liberare la struttura, si sarebbe fregato.
Una seconda interpretazione è che "PID" restituisce un array di puntatori a DEV_INFO strutture. Abbastanza probabile dato l'argomento "n", il che potrebbe significare il numero di elementi nella matrice si passa per essere riempito dalla funzione. In tal caso, passare un IntPtr [] e impostare "n" per la sua lunghezza.
Altri suggerimenti
È necessario creare un struct
in C # che rispecchia la PDEV_INFO
struct
C ++ in C ++.
Si dovrebbe applicare [StructLayout(LayoutKind.Sequential)]
alla struct e quindi copiare i campi della struct C ++ (guarda il file di intestazione) in ordine.
È quindi possibile scrivere un metodo che prende il extern
struct
come parametro ref
.
Si assume in modo sicuro PDEV_INFO*
è un DEV_INFO**
.
Con questo in C #:
class DEV_INFO
{
// fields go here
}
static class NativeMethods
{
[DllImport...]
public static extern int hid_get_info(int n, ref DEV_INFO pdi);
}