2013-01-23 52 views
2

我正在将旧的Visual BASIC程序转换为C#。该程序通过串行或以太网线路将消息发送给某些工业机器。为此,它创建一个消息的字节数组。将不同的结构体复制到字节数组

问题是存在不同的消息格式,每个消息格式都在VB6中定义为用户定义的类型。例如。

Public Type K_QCHECK 
    Header As K_HEADER3 
    Count As LNG4 
    crc As INT2 
End Type 

(LNG4和INT2的是自定义的类型)通过自动翻译工具,我得到一个C#结构运行VB6代码:

public struct K_QCHECK 
{ 
    public K_HEADER3 Header; 
    public LNG4 Count; 
    public INT2 crc; 
} 

但复制这些字节数组与旧VB6代码LSET。这取决于这种假设,即类型代表了连续的记忆块。但是在C#中,编译器在内存中布置东西的方式应该是程序员无法访问的实现细节。

那么,将这些不同结构的内容转换为字节数组的最佳方式是什么?我可以让每个人都成为一个类,并给它一个CopyToByteArray方法或运算符,但其中有50个这样看起来像很多工作。在此先感谢您的任何建议!

+0

序列化:) http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx – gustavodidomenico

+0

我认为序列化不会产生原始数据的字节对字节复制结构,因为它可能包含元数据。 – user316117

回答

3

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

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

+1

你为什么说这可能不是正确的解决方案?搜索网页,所以我看到的几乎所有的解决方案都涉及到非托管代码,并进行某种字节的复制。但是他们中很少有人提到这样的缺陷:对齐和布局可能与编码者认为他在C#中编码的内容不相似。您的答案为此提供了明显的解决方案,因此它可能是(部分)正确的解决方案。 – user316117

+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; 
    } 
+0

上述内容是否假定结构中的数据是内部布局的,内存中的布局与源代码中的顺序相同,是连续的,没有用于对齐的填充?我不认为这些在C#中是可靠的假设。 – user316117

+0

Roman Royter的答案可能会提供解决方法。 – user316117

相关问题