> 백엔드 개발 > C++ > C/C 바이트 배열을 C# 구조로 효율적으로 변환하는 방법은 무엇입니까?

C/C 바이트 배열을 C# 구조로 효율적으로 변환하는 방법은 무엇입니까?

Mary-Kate Olsen
풀어 주다: 2025-01-19 06:12:11
원래의
980명이 탐색했습니다.

How to Efficiently Convert a C/C   Byte Array to a C# Structure?

바이트 배열에서 C#으로 C/C 데이터 구조 읽기

질문

이 작업에는 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));
    }
}
로그인 후 복사

BinaryReader를 사용하여 성능 향상

선호되는 솔루션에는 고정 및 Marshal.PtrToStructure이 포함되지만 경우에 따라 BinaryReader 클래스를 사용하여 데이터를 구문 분석하면 성능 이점을 제공할 수 있습니다. 그러나 그러한 이득이 중요한지 여부를 결정하려면 특정 구현을 평가해야 합니다.

위 내용은 C/C 바이트 배열을 C# 구조로 효율적으로 변환하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿