2013-01-23 74 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

相關問題