Вопрос

Я пытаюсь использовать некоторый код pinvoke для вызова функции C. Функция заполняет буфер данными.

Структура задается как DWORD для длины, за которой следует строка. Как извлечь строку из IntPtr?

 IntPtr buffer = Marshal.AllocHGlobal(nRequiredSize);
 PInvokedFunction(buffer, nRequiredSize);
 string s = Marshal.PtrToStringAuto(buffer + 4); //this is an error.
 Marshal.FreeHGlobal(buffer);
Это было полезно?

Решение

Вы должны сделать это:

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

Итак, ваш код безопасен на 64 бита.

Другие советы

Лучшее, что я мог придумать, было следующее, хотя использование UnmanagedMemoryStream кажется чем-то вроде хака.

 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);

Кажется, это работает, хотя мне кажется, что мне больше нравится ответ Мэтта Эллиса .

Я изменил IntPtr на [DllImport] на байт [].

 //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));
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top