题
我正在尝试使用一些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);
这似乎有效,但我认为我更喜欢马特埃利斯的答案。
我将[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));
不隶属于 StackOverflow