我(成功)使用以下 pinvoke 签名在 c# 中调用 Windows FilterSendMessage 函数:
[DllImport("fltlib.dll")]
public static extern IntPtr FilterSendMessage(
IntPtr hPort,
IntPtr inBuffer,
UInt32 inBufferSize,
IntPtr outBuffer,
UInt32 outBufferSize,
out UInt32 bytesReturned);
outBuffer参数填充了任意数量的结构(一个接一个地打包),在 C 中定义为:
typedef struct _BAH_RECORD {
int evt
int len;
WCHAR name[1];
} BAH_RECORD, *PBAH_RECORD;
名称字段被分配了一个可变长度、以空字符结尾的 unicode 字符串。len字段以字节为单位描述结构的总大小(包括名称字符串)。我相信在非托管方面如何处理结构没有任何问题。
当我尝试将 outBuffer 编组到 C# 中定义为 BAH_RECORD 结构的实例时,我的问题出现了:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct BAH_RECORD
{
public UInt32 evt;
public UInt32 len;
public string name;
}
IntPtr outBuffer = Marshal.AllocHGlobal(OUT_BUFFER_SIZE);
hResult = Win32.FilterSendMessage(hPortHandle, inBuffer, IN_BUFFER_SIZE, outBuffer, OUT_BUFFER_SIZE, out bytesReturned);
BAH_RECORD bah = (BAH_RECORD)Marshal.PtrToStructure(outBuffer, typeof(BAH_RECORD));
<snip>
如果我尝试打印/查看/显示 bah.name,我会得到垃圾......
为了确认 outBuffer 确实包含有效数据,我在 c# 中做了一些粗略的指针骇客来逐步处理它,调用 Marshal.ReadInt32 两次(以覆盖前 2 个结构字段),然后调用 Marshal.ReadByte 几次以填充一个字节[] 然后我将其用作 Encoding.Unicode.GetString() 的参数......字符串出来很好,所以它肯定在那里,我似乎无法让编组器正确处理它(如果它甚至能够?)
任何帮助表示赞赏
史蒂夫