Я (успешно) вызываю функцию Windows FilterSendMessage в c #, используя следующую подпись pinvoke:
[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;
Полю name присваивается переменная длина строки Unicode с нулевым символом в конце. Поле len описывает общий размер структуры в байтах (включая строку имени). Я уверен, что нет ничего плохого в том, как обрабатываются структуры в неуправляемой стороне вещей.
Моя проблема возникает, когда я пытаюсь маршалировать outBuffer в экземпляр структуры BAH_RECORD, определенной в c # как:
[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, чтобы заполнить byte [], который я затем использую в качестве аргумента для Encoding.Unicode.GetString () ... строка получается нормально, так что она определенно есть, я просто не могу заставить маршаллера правильно ее обработать ( если это вообще может?)
Любая помощь приветствуется
Steve