필자는 원격 에이전트가 직렬화 된 구조 (임베디드 C 시스템에서)를 보내 IP/UDP를 통해 읽고 저장할 수있는 시스템을 가지고 있습니다. 어떤 경우에는 동일한 구조 유형을 다시 전송해야합니다. 나는 Marshal.PtrToStructure (receive)와 Marshal.StructureToPtr (send)를 사용하여 좋은 설정이 있다고 생각했다. 그러나 작은 문제는 네트워크 빅 엔디안 정수를 로컬에서 사용하기 위해 x86 리틀 엔디안 형식으로 변환해야한다는 것입니다. 내가 그들을 다시 보낼 때 빅 엔디안이 갈 길입니다.Marshal.PtrToStructure (그리고 다시) endianness swapping을위한 일반 솔루션
private static T BytesToStruct<T>(ref byte[] rawData) where T: struct
{
T result = default(T);
GCHandle handle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
try
{
IntPtr rawDataPtr = handle.AddrOfPinnedObject();
result = (T)Marshal.PtrToStructure(rawDataPtr, typeof(T));
}
finally
{
handle.Free();
}
return result;
}
private static byte[] StructToBytes<T>(T data) where T: struct
{
byte[] rawData = new byte[Marshal.SizeOf(data)];
GCHandle handle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
try
{
IntPtr rawDataPtr = handle.AddrOfPinnedObject();
Marshal.StructureToPtr(data, rawDataPtr, false);
}
finally
{
handle.Free();
}
return rawData;
}
그리고 다음과 같이 사용될 수있는 간단한 구조 예 :
byte[] data = this.sock.Receive(ref this.ipep);
Request request = BytesToStruct<Request>(ref data);
문제의 구조는 다음과 같습니다
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
private struct Request
{
public byte type;
public short sequence;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] address;
}
다음
는 문제의 함수이다
구조를 정렬 할 때 엔디안을 어떻게 교환 할 수 있습니까? 이 예제에서 로컬에 저장된 'request.sequence'는 사용자에게 표시하기 위해 리틀 엔디안이어야합니다. 나는 그것이 일반적인 문제이기 때문에 구조 고유의 방식으로 엔디안을 교환하고 싶지 않습니다.
내 첫 번째 생각은 리플렉션을 사용하는 것이었지만 그 기능에 익숙하지 않았습니다. 또한 누군가가 나를 향해 더 나은 해결책을 제시 할 수 있기를 바랬다. 미리 감사드립니다 :)
누군가가 우리가 같은 qeuestion (http : // stackoverflow)을 요구하고 있음을 지적하는 데 어떻게 2 년이 걸렸습니까?com/questions/2480116/marshalling-a-big-endian-byte-collection-into-a-struct-in-order-to-out-value) !? :-) – Pat