Feedback

VB - Generic struct<->byte[] Marshalling

Veröffentlicht von am 6/27/2015
(0 Bewertungen)
A very small class that offers generic methods for marshalling byte arrays to structures and backwards. Structures must be signed as sequential by StructLayout attribute.
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
Abgelegt unter Marshalling, Byte, Array, Structure.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!