2009-09-14 11 views
7

Nel tentativo di imparare a usare PInvoke in C#, sono un po 'incerto su come gestire vari casi con puntatori che coinvolgono tipi di valori semplici.Come P/Invoke quando sono coinvolti i puntatori

sto importando i seguenti due funzioni da una DLL non gestita:

public int USB4_Initialize(short* device); 
public int USB4_GetCount(short device, short encoder, unsigned long* value); 

La prima funzione utilizza il puntatore come ingresso, la seconda come uscita. Il loro utilizzo è abbastanza semplice in C++:

// Pointer as an input 
short device = 0; // Always using device 0. 
USB4_Initialize(&device); 

// Pointer as an output 
unsigned long count; 
USB4_GetCount(0,0,&count); // count is output 

Il mio primo tentativo in C# genera il seguente P/Richiama:

[DllImport("USB4.dll")] 
public static extern int USB4_Initialize(IntPtr deviceCount); //short* 

[DllImport("USB4.dll")] 
public static extern int USB4_GetCount(short deviceNumber, short encoder, IntPtr value); //ulong* 

Come faccio ad usare queste funzioni in C# nello stesso modo come il Codice C++ sopra? C'è un modo migliore per dichiarare questi tipi, forse usando MarshalAs?

+0

Ehi, USB 4 già? Sto ancora aspettando 3.0 –

+1

Vorrei. Non ha nulla a che fare con USB4. Questo è solo un dispositivo USB che l'azienda ha per la connessione a un encoder e, poiché è la quarta revisione del loro prodotto, ha stupidamente chiamato il prodotto USB4. –

risposta

12

Se il puntatore è ad un solo tipo primitivo e non un array, rif/a descrivere il parametro

[DllImport("USB4.dll")] 
public static extern int USB4_Initialize(ref short deviceCount); 

[DllImport("USB4.dll")] 
public static extern int USB4_GetCount(short deviceNumber, short encoder, ref uint32 value) 

In questi esempi Out è probabilmente più appropriato ma o funzionerà.

+0

Quindi in GetCount() posso utilizzare invece di ref? –

+0

Vedo, questo è esattamente quello che speravo. Grazie. –

+0

Yep stava per dire la stessa cosa, tranne che per avere la definizione USB4_GetCount – zebrabox

0

Il runtime .NET può fare molto per quella conversione (denominata "marshalling"). Mentre un IntPtr esplicito farà sempre ESATTAMENTE ciò che gli dici, puoi probabilmente sostituire la parola chiave ref con un puntatore del genere.

[DllImport("USB4.dll")] 
public static extern int USB4_Initialize(ref short deviceCount); //short* 

[DllImport("USB4.dll")] 
public static extern int USB4_GetCount(short deviceNumber, short encoder, ref short value); //ulong* 

È quindi possibile chiamare in questo modo:

short count = 0; 

USB4_Initialize(ref count); 

// use the count variable now. 
Problemi correlati