Imports System.Runtime.InteropServices
Public Class SequentialStructureMarshalling
Public Shared Function StructureToByteArray(Of TStructure As Structure)(sourceStructure As TStructure) As Byte()
Dim structureType As Type = GetType(TStructure)
If structureType.StructLayoutAttribute.Value <> LayoutKind.Sequential Then
Throw New ArgumentException("The generic type parameter TStructure must be sequential, but was not!", "TStructure")
End If
Dim structureSize As Integer = Marshal.SizeOf(structureType)
Dim destinationPointer As IntPtr = Marshal.AllocHGlobal(structureSize)
Marshal.StructureToPtr(sourceStructure, destinationPointer, True)
Dim byteArray(structureSize - 1) As Byte
Marshal.Copy(destinationPointer, byteArray, 0, structureSize)
Marshal.FreeHGlobal(destinationPointer)
Return byteArray
End Function
Public Shared Function ByteArrayToStructure(Of TStructure As Structure)(startIndex As Integer, ParamArray byteArray As Byte()) As TStructure
If startIndex < 0 Then
Throw New ArgumentException("The startIndex parameter must be greater than 0, but was not!", "startIndex")
End If
Dim structureType As Type = GetType(TStructure)
If structureType.StructLayoutAttribute.Value <> LayoutKind.Sequential Then
Throw New ArgumentException("The generic type parameter TStructure must be sequential, but was not!", "TStructure")
End If
Dim structureSize As Integer = Marshal.SizeOf(structureType)
If byteArray.Length < (startIndex + structureSize) Then
Throw New ArgumentException("The length of the byteArray parameter must be greater or equal to the structure length plus startIndex, but was not!", "array")
End If
Dim destinationPointer As IntPtr = Marshal.AllocHGlobal(structureSize)
Marshal.Copy(byteArray, startIndex, destinationPointer, structureSize)
Dim structureResult As TStructure = DirectCast(Marshal.PtrToStructure(destinationPointer, structureType), TStructure)
Marshal.FreeHGlobal(destinationPointer)
Return structureResult
End Function
End Class