问题
I'm converting an old Visual BASIC program to C#. The program sends messages to some industrial machinery over a serial or ethernet line. To do this it creates a byte array of the message.
The problem is that there are MANY (~50) different message formats, each one defined in VB6 as a user-defined type. For example.
Public Type K_QCHECK
Header As K_HEADER3
Count As LNG4
crc As INT2
End Type
(LNG4 and INT2's are custom types) Running the VB6 code through an automated translation tool I get a C# struct:
public struct K_QCHECK
{
public K_HEADER3 Header;
public LNG4 Count;
public INT2 crc;
}
But the old VB6 code copied these to the byte array with an LSet. This depended on the assumption that the types represented a contiguous block of memory. But in C# the way stuff is laid-out by the compiler in memory is supposed to a be an implementation detail not accessible to the programmer.
So what's the best way to get the contents of these different structs into a byte array? I could make each one a class and give it a CopyToByteArray method or operator but there are 50 of these so that seems like a lot of work. Thanks in advance for any suggestions!
回答1:
This is probably not the right solution, but there is a StructLayoutAttribute which lets you define explicitly how the struct is laid out in memory.
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute%28v=vs.110%29.aspx
回答2:
Using these codes you can convert between any structure
and it's byte[]
array representation. No need to implement separate method for every structure.
public static byte[] StructureToByteArray<T>(T structure) where T:struct
{
int len = Marshal.SizeOf(structure);
byte[] result = new byte[len];
IntPtr ptr = Marshal.AllocHGlobal(len);
Marshal.StructureToPtr(structure, ptr, true);
Marshal.Copy(ptr, result, 0, len);
Marshal.FreeHGlobal(ptr);
return result;
}
public static T ByteArrayToStructure<T>(byte[] buffer) where T:struct
{
//int len = Marshal.SizeOf(typeof(T));
int length = buffer.Length;
IntPtr i = Marshal.AllocHGlobal(length);
Marshal.Copy(buffer, 0, i, length);
T result = (T)Marshal.PtrToStructure(i, typeof(T));
Marshal.FreeHGlobal(i);
return result;
}
来源:https://stackoverflow.com/questions/14485653/copying-different-structs-to-byte-arrays