IP/UDP aracılığıyla okumak ve saklamak için uzak bir ajanın serileştirilmiş yapıları (gömülü C sisteminden) gönderdiği bir sistemim var. Bazı durumlarda aynı yapı tiplerini geri göndermem gerekiyor. Marshal.PtrToStructure (alma) ve Marshal.StructureToPtr (gönder) kullanarak güzel bir kurulum olduğunu düşündüm. Ancak, küçük bir çentik, ağın büyük endian tam sayılarının yerel olarak kullanılmak üzere x86 küçük endian formatına dönüştürülmesi gerektiğidir. Onları tekrar gönderdiğimde, büyük endian gitmek için yoldur.Marshal.PtrToStructure ve endianness takas için genel çözüm
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;
}
Ve böyle kullanılabilecek hızlı bir örnek yapısı:
byte[] data = this.sock.Receive(ref this.ipep);
Request request = BytesToStruct<Request>(ref data);
Söz konusu yapı gibi görünür:
[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;
}
İşte
söz konusu fonksiyonlar
Yapıları sıralarken ne (jenerik) bir şekilde endoteliteyi değiştirebilirim? İhtiyacım şudur, bu örnekte yerel olarak saklanan 'request.sequence', kullanıcıya gösterilmek üzere az-endian olmalıdır. Genel bir sorun olduğundan, enderliği yapıya özel bir şekilde değiştirmek istemiyorum.
İlk düşüncem Reflection kullanmaktı, ama bu özelliğe aşina değilim. Ayrıca, birilerinin bana doğru yönlendirebileceği daha iyi bir çözüm olacağını umuyorum. Şimdiden teşekkürler :)
Birinin aynı sorgulamayı (http: // stackoverflow) istediğimizi belirtmesi iki yıl nasıl geçti?com/sorular/2480116/sıralanırken-a-büyük-endian bayt-toplama-içine-a-yapı-in-düzen-to-pull-out-valu) !? :-) – Pat