이 작업에는 C/C 구조의 데이터가 포함된 바이트 배열을 해당 C# 구조로 변환하는 작업이 포함됩니다. C/C 구조는 다음과 같습니다.
typedef struct OldStuff { CHAR Name[8]; UInt32 User; CHAR Location[8]; UInt32 TimeStamp; UInt32 Sequence; CHAR Tracking[16]; CHAR Filler[12]; } OldStuff;
NewStuff
이라는 C# 구조는 다음과 같이 정의됩니다.
[StructLayout(LayoutKind.Explicit, Size = 56, Pack = 1)] public struct NewStuff { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] [FieldOffset(0)] public string Name; [MarshalAs(UnmanagedType.U4)] [FieldOffset(8)] public uint User; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] [FieldOffset(12)] public string Location; [MarshalAs(UnmanagedType.U4)] [FieldOffset(20)] public uint TimeStamp; [MarshalAs(UnmanagedType.U4)] [FieldOffset(24)] public uint Sequence; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] [FieldOffset(28)] public string Tracking; }
처음에는 고정된 메모리를 사용하고 Marshal.PtrToStructure
:
int BufferSize = Marshal.SizeOf(typeof(NewStuff)); byte[] buff = new byte[BufferSize]; Array.Copy(SomeByteArray, 0, buff, 0, BufferSize); handle = GCHandle.Alloc(buff, GCHandleType.Pinned); MyStuff = (NewStuff)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(NewStuff)); handle.Free();
추가 분석 결과 원래 방식의 버퍼 복사가 불필요한 것으로 확인되었습니다. 대신 직접 핸들 고정으로 충분합니다.
GCHandle handle; NewStuff MyStuff; handle = GCHandle.Alloc(SomeByteArray, GCHandleType.Pinned); try { MyStuff = (NewStuff)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(NewStuff)); } finally { handle.Free(); }
또한 제네릭을 사용하여 더욱 간단한 버전을 사용할 수도 있습니다(안전하지 않은 전환 필요).
T ByteArrayToStructure<T>(byte[] bytes) where T : struct { T stuff; GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); } finally { handle.Free(); } return stuff; }
unsafe T ByteArrayToStructure<T>(byte[] bytes) where T : struct { fixed (byte* ptr = &bytes[0]) { return (T)Marshal.PtrToStructure((IntPtr)ptr, typeof(T)); } }
선호되는 솔루션에는 고정 및 Marshal.PtrToStructure
이 포함되지만 경우에 따라 BinaryReader
클래스를 사용하여 데이터를 구문 분석하면 성능 이점을 제공할 수 있습니다. 그러나 그러한 이득이 중요한지 여부를 결정하려면 특정 구현을 평가해야 합니다.
위 내용은 C/C 바이트 배열을 C# 구조로 효율적으로 변환하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!