VB.NET 4.5Как избежать избыточного байта, когда структура содержит байтовую переменную? (VB.NET)
У меня есть структура, которая содержит один байт. Мне нужно получить массив байтов, который будет отправлен через последовательный порт.
Public Structure ExampleStructure
Public variable1 As Byte
Public variable2 As UInt16
Public variable3 As UInt16
Public Function getBytes() As Byte()
Dim binaryBytes(5) As Byte
Dim pointerCommand As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Me))
Marshal.StructureToPtr(Me, pointerCommand, False)
Marshal.Copy(pointerCommand, binaryBytes, 0, Marshal.SizeOf(Me))
Marshal.FreeHGlobal(pointerCommand)
Return binaryBytes
End Function
End Structure
Этот вопрос:
, когда я использую Marshal.AllocHGlobal
, Marshal.StructureToPtr
и Marshal.Copy
массив байт Возвращается 6 байт. .NET создает 2 байта для переменной1, поэтому имеется избыточный байт между данными переменной1 и переменной2.
Я могу решить эту проблему с помощью LayoutKind.Explicit
и определения FieldOffsets.
<StructLayout(LayoutKind.Explicit)> _
Public Structure ExampleStructure
<FieldOffset(0)> Public variable1 As Byte
<FieldOffset(1)> Public variable2 As UInt16
<FieldOffset(3)> Public variable3 As UInt16
Public Function getBytes() As Byte()
Dim binaryBytes(5) As Byte
Dim pointerCommand As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Me))
Marshal.StructureToPtr(Me, pointerCommand, False)
Marshal.Copy(pointerCommand, binaryBytes, 0, Marshal.SizeOf(Me))
Marshal.FreeHGlobal(pointerCommand)
Return binaryBytes
End Function
End Structure
Теперь, когда я получаю байты, больше нет избыточного байта между переменной1 и переменной2.
Это похоже на неуклюжий способ сделать это. Есть ли лучший вариант, когда мне не нужно вручную устанавливать FieldOffsets? Эта структура проста, но они могут стать намного более сложными.
компилятор пытается оптимизировать код, совместив данные на 16-битной границе. Таким образом, вы боретесь с оптимизатором компилятора. В наши дни микропроцессоры работают быстрее, когда коды выровнены по более широким границам. Не уверен, есть ли опция компилятора для принудительного выравнивания кода на границах байтов. Попробуйте: LayoutKind.Sequential – jdweng
Я просто попробовал LayoutKind.Sequential, но не повезло. – user2347261
Try pack option: [StructLayout (LayoutKind.Sequential, Pack = 8)] – jdweng