2

我正在将旧的 Visual BASIC 程序转换为 C#。该程序通过串行或以太网线路向某些工业机械发送消息。为此,它会创建消息的字节数组。

问题在于有许多(约 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 个,所以这似乎需要大量工作。在此先感谢您的任何建议!

4

2 回答 2

3

这可能不是正确的解决方案,但是有一个 StructLayoutAttribute 可以让您明确定义结构在内存中的布局方式。

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute%28v=vs.110%29.aspx

于 2013-01-23T17:28:22.743 回答
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;
    }
于 2013-01-23T17:32:52.200 回答