我正在尝试使用一些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));
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top