2010-01-03 23 views
7

In C# PInvoke, come faccio a passare un buffer di stringa in modo che la DLL C lo riempia e restituisca? Quale sarà la dichiarazione di PInvoke?C# PInvoke out string declaration

La dichiarazione di funzione C è

int GetData(char* data, int buflength); 

In C#, ho dichiarato come

[DllImport(DllName)] 
static extern Int32 GetData([MarshalAs(UnmanagedType.LPStr)]StringBuilder receiveddata, Int32 buflen); 

E 'corretto? Sto passando la variabile StringBuilder come questo

int bufferLength = 32; 
StringBuilder data = new StringBuilder(bufferLength); 
int result = GetData(data, bufferLength); 

vorrei sapere è corretto o no?

Grazie

+0

E 'corretto se funziona. Non c'è una ragione ovvia che non dovrebbe funzionare. –

risposta

7

Credo sia corretto.

[DllImport(DllName)] 
static extern int GetData(StringBuilder data, int length); 

che si chiama in questo modo:

StringBuilder data = new StringBuilder(32); 
GetData(data, data.Capacity); 

una volta ho voluto avere un maggiore controllo sulle byte restituiti dalla mia funzione e lo ha fatto in questo modo:

[DllImport(DllName)] 
private unsafe static bool GetData(byte* data, int length); 

usato come questo :

byte[] bytes = new byte[length]; 

fixed(byte* ptr = bytes) 
{ 
    bool success = Library.GetData(ptr, length); 

    if (!success) 
    Library.GetError(); 

    return Encoding.UTF8.GetString(bytes); 
} 
3

Faccio non pensare che l'uso dell'attributo MarshalAs sia necessario qui. StringBuilder è una scelta giusta per char * out.

Suppongo che sarà opportuno aggiungere la proprietà CharSet poiché si tratta di stringhe qui.

Ti piace questa:

[DllImport(DllName, CharSet=CharSet.Auto)]