Вы должны убедиться, что структура, которую вы маршалируете, имеет ту же структуру, что и собственная структура, используя атрибут StructLayout
, например.
[<type: StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)>]
type OneDevice = {
...
Кроме того, вам необходимо явно пометить любые поляс атрибутом MarshalAs
, если им требуется маршалинг с маршалингом не по умолчанию, таким как массивы.Маршалинг по умолчанию для массивов LPArray
, но, судя по его звукам, ваша нативная структура ожидает ByValArray
.
[<field: MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)>]
mutable pwd : byte array
Наконец, замените GCHandle.Alloc
на Marshal.AllocHGlobal
для выделения неуправляемыхпамяти и используйте Marshal.FreeHGlobal
для его освобождения.
Примечание: я не уверен, могут ли типы записей F # принимать эти атрибуты, но я ожидаю, что они будут работать.Если нет, то вам нужно будет использовать их в сочетании с предложением jpalmer использовать struct
.
Редактировать:
let size = Marshal.SizeOf(typeof<OneDevice>)
let unmanagedPtr = Marshal.AllocHGlobal(size)
Marshal.StructureToPtr(device, unmanagedPtr, false)
Marshal.Copy(unmanagedPtr, bytes, 0, size)
Marshal.FreeHGlobal(unmanagedPtr)
Редактировать:
Выше указанодля копирования заполненной структуры OneDevice в пустой байтовый массив.Если вы хотите сделать обратное - преобразование заполненного байтового массива в структуру, это в значительной степени одно и то же.
let size = Marshal.SizeOf(typeof<OneDevice>)
let unmanagedPtr = Marshal.AllocHGlobal(size)
Marshal.Copy(bytes, unmanagedPtr, 0, size)
Marshal.PtrToStructure(unmanagedPtr, device)
Marshal.FreeHGlobal(unmanagedPtr)