2013-11-25 197 views
0

我有一個結構定義爲marshal.PtrToStructure訪問衝突錯誤時拋出

[StructLayout(LayoutKind.Sequential,Pack=1)] 
    private struct networkMessage 
     { 
     public messageType type; 
     public string message; 
     } 

,我有這個功能的結構轉換成byte[]

private byte[] ConvertToByteArray(networkMessage inStruct) 
     { 
     int structSize = Marshal.SizeOf(inStruct); 
     byte[] byteArray = new byte[structSize]; 

     IntPtr memPtr = IntPtr.Zero; 

     try 
      { 
      memPtr = Marshal.AllocHGlobal(structSize); 
      Marshal.StructureToPtr(inStruct, memPtr, false); 
      Marshal.Copy(memPtr, byteArray, 0, structSize); 
      } 
     finally 
      { 
      if (memPtr != IntPtr.Zero) 
       { 
       Marshal.FreeHGlobal(memPtr); 
       } 
      } 
     foreach (byte b in byteArray) 
      { 
      Console.WriteLine(b + " "); 
      } 

     return byteArray; 
     } 

,這回要轉換成一個struct

private networkMessage ConvertFromByteArray(byte[] inByte) 
     { 
     foreach (byte b in inByte) 
      { 
      Console.WriteLine(b); 
      } 

     GCHandle handle = GCHandle.Alloc(inByte, GCHandleType.Pinned); 

     networkMessage outStruct = (networkMessage) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(networkMessage)); //---Exception here 

     return outStruct; 
     } 

這用於一個TCP應用程序,它既充當服務器又充當客戶端,這樣相同的可執行文件在兩臺機器上運行。在對象構造函數中測試轉換表明它工作正常,但來自另一臺計算機的字節數組會導致訪問衝突異常。在兩個系統上打印字節表明它們是相同的。可能是什麼問題呢?我認爲這可能與該結構有關?

+1

這應該總是崩潰。 * message *字段缺少所需的[MarshalAs]屬性來聲明它ByValTStr,同樣需要SizeConst。 –

回答

1

這是行不通的。

試試這個:將message設置爲一個比16個字符長的字符串,然後看看Marshal.SizeOf(inStruct)的值。不管message的長度如何,對於64位版本將是12,對於32位版本將是8。

正確的解決方案是使用序列化來轉換數據。

您可能想要查看NetTcpBinding,它可以使用DataContracts來序列化數據。另外,看看JSON serialization