본문 바로가기

개발자/WPF(C#) UI

C# :: byte[] -> 구조체 , 구조체 -> byte(바이트배열 구조체간 할당)

반응형
//byte 배열을 구조체로

public static object ByteToStructure(byte[] data, Type type)

{

    IntPtr buff = Marshal.AllocHGlobal(data.Length); // 배열의 크기만큼 비관리 메모리 영역에 메모리를 할당한다.

    Marshal.Copy(data, 0, buff, data.Length); // 배열에 저장된 데이터를 위에서 할당한 메모리 영역에 복사한다.
    object obj = Marshal.PtrToStructure(buff, type); // 복사된 데이터를 구조체 객체로 변환한다.

    Marshal.FreeHGlobal(buff); // 비관리 메모리 영역에 할당했던 메모리를 해제함



    if (Marshal.SizeOf(obj) != data.Length)// (((PACKET_DATA)obj).TotalBytes != data.Length) // 구조체와 원래의 데이터의 크기 비교

    {

    return null; // 크기가 다르면 null 리턴

    }

return obj; // 구조체 리턴

}




// 구조체를 byte 배열로

public static byte[] StructureToByte(object obj)

{

    int datasize = Marshal.SizeOf(obj);//((PACKET_DATA)obj).TotalBytes; // 구조체에 할당된 메모리의 크기를 구한다.

    IntPtr buff = Marshal.AllocHGlobal(datasize); // 비관리 메모리 영역에 구조체 크기만큼의 메모리를 할당한다.

    Marshal.StructureToPtr(obj, buff, false); // 할당된 구조체 객체의 주소를 구한다.

    byte[] data = new byte[datasize]; // 구조체가 복사될 배열

    Marshal.Copy(buff, data, 0, datasize); // 구조체 객체를 배열에 복사

    Marshal.FreeHGlobal(buff); // 비관리 메모리 영역에 할당했던 메모리를 해제함

    return data; // 배열을 리턴

}

 

 

 

 

좀 소스 그대로긴 해도 소켓통신에서 사용할때 도움이 많이 될거 같습니다.

 

그리고 사용시 주의 사항은 Marshal.SizeOf(obj); 이부분입니다.

 

struct PACKET_DATA

{
            public int PacketType;         // 패킷 타입
            public int TotalBytes;
            public byte[] Data;// 배열길이 1024

  }

이런 구조체가 있다면 ..

Marshal.SizeOf(obj)는 byte의 배열 을 생각 안하고

사이즈를 무조건 12를 리턴합니다.

그럼 네트워크 통신에 데이터를 다 못 보내기 때문에~~

구조체 안에 크기를 선언해줍니다.

 

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]

struct PACKET_DATA

{
            public int PacketType;         // 패킷 타입
            public int TotalBytes;

           [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)] 
            public byte[] Data;//byte배열 길이 1024

}

그럼 Marshal.SizeOf(obj)는 1032를 리턴합니다~~~



 

참고 URL : https://202psj.tistory.com/1252

반응형