我正在将旧的Visual BASIC程序转换为C#。该程序通过串行或以太网线路向某些工业机械发送消息。为此,它会创建一个消息的字节数组。
问题是 MANY (~50)种不同的消息格式,每种格式在VB6中定义为用户定义的类型。例如。
Public Type K_QCHECK
Header As K_HEADER3
Count As LNG4
crc As INT2
End Type
(LNG4和INT2是自定义类型)通过自动翻译工具运行VB6代码我得到一个C#结构:
public struct K_QCHECK
{
public K_HEADER3 Header;
public LNG4 Count;
public INT2 crc;
}
但是旧的VB6代码将这些代码复制到带有LSet的字节数组中。这取决于假设类型代表连续的内存块。但是在C#中,编译器在内存中布局的方式应该是程序员无法访问的实现细节。
那么将这些不同结构的内容放入字节数组的最佳方法是什么?我可以让每个人都成为一个类,并给它一个CopyToByteArray方法或运算符,但有50个这样的,所以这似乎很多工作。提前感谢任何建议!
答案 0 :(得分:3)
这可能不是正确的解决方案,但有一个StructLayoutAttribute允许您明确定义结构在内存中的布局。
答案 1 :(得分:1)
使用这些代码,您可以在任何structure
和byte[]
数组表示之间进行转换。无需为每个结构实现单独的方法。
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;
}