2

我正在尝试使用一些 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);
4

3 回答 3

3

你应该做这个:

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

所以你的代码是 64 位安全的。

于 2008-10-18T22:30:48.390 回答
0

我能想出的最好的方法是以下,尽管 UnmanagedMemoryStream 的使用似乎有点 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);
于 2008-10-18T21:58:44.430 回答
0

这似乎有效,尽管我认为我更喜欢马特埃利斯的答案

我将 [DllImport] 上的 IntPtr 更改为 byte[]。

 //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));
于 2008-10-18T23:15:40.843 回答