2008-10-18 11 views
2

J'essaie d'utiliser un code pinvoke pour appeler une fonction C. La fonction remplit un tampon avec des données.Pointer math en C#

La structure est définie en tant que DWORD pour la longueur, suivie d'une chaîne. Comment puis-je extraire la chaîne de l'IntPtr?

IntPtr buffer = Marshal.AllocHGlobal(nRequiredSize); 
PInvokedFunction(buffer, nRequiredSize); 
string s = Marshal.PtrToStringAuto(buffer + 4); //this is an error. 
Marshal.FreeHGlobal(buffer); 

Répondre

3

Vous devriez faire ceci:

IntPtr sBuffer = new IntPtr(buffer.ToInt64() + 4); 
string s = Marshal.PtrToStringAuto(sBuffer); 

donc votre code est 64bit sûr.

0

Le mieux que je pouvais trouver était la suivante, bien que l'utilisation de l'UnmanagedMemoryStream semble un peu un hack.

IntPtr buffer = Marshal.AllocHGlobal((int)nRequiredSize); 
PInvokedFunction(buffer, nRequiredSize); 
UnmanagedMemoryStream memStream = new UnmanagedMemoryStream(buffer.ToPointer(), nRequiredSize); 
memStream.Seek(4, SeekOrigin.Begin); 
IntPtr ptr = new IntPtr(memStream.PositionPointer); 
string s = Marshal.PtrToStringAuto(ptr); 
Marshal.FreeHGlobal(buffer); 
0

Cela a semblé fonctionner, bien que je pense que j'aime mieux Matt Ellis's Answer.

J'ai changé IntPtr sur [DllImport] en octet [].

//allocate the buffer in .Net 
byte[] buffer = new byte[nRequiredSize]; 

//call the WIN32 function, passing it the allocated buffer 
PInvokedFunction(buffer); 

//get the string from the 5th byte 
string s = Marshal.PtrToStringAuto(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 4));