//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를 리턴합니다~~~

'Language > C#' 카테고리의 다른 글

C# :: iTextSharp (PDF 문서 만들기)  (0) 2015.09.17
C# :: SourceGrid  (0) 2015.01.13
C# :: Bootstrapper Manifest Generator  (0) 2011.12.19
C# :: MS Chart  (0) 2011.12.19
C# :: MSChart 설치  (0) 2011.12.19

+ Recent posts