2017-02-06 159 views
1

我有以下嵌套結構。C#嵌套結構封送 - 對象

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
struct ERROR_ITEM 
{ 
    byte ErrorID; 
}; 

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
struct ERROR_DATA 
{ 
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 10)] 
    ERROR_ITEM[] ErrorItem; 

}; 

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
struct VCP_DATA 
{ 
    [MarshalAs(UnmanagedType.Struct)] 
    ERROR_DATA ErrorData; 
}; 

我需要一個字節數組複製這樣的結構,所以我嘗試以下

vcpBuffer = new VCP_DATA();  
GCHandle handle = GCHandle.Alloc(vcpBuffer, GCHandleType.Pinned); 
try 
{ 
    IntPtr pBuffer = handle.AddrOfPinnedObject(); 
    Marshal.Copy(bytarray, 0, pBuffer, length); 
} 
finally 
{ 
    if (handle.IsAllocated) 
     handle.Free(); 
} 

但是GCHandle.Alloc()返回錯誤「類型System.Argument.Execption的未處理的異常「發生在mscorlib.dll中。 附加信息:對象包含非原始數據或不可接受數據。

回答

0
vcpBuffer = new VCP_DATA(); 
GCHandle handle = GCHandle.Alloc(bytearray, GCHandleType.Pinned); 
try 
{ 
    IntPtr pBuffer = handle.AddrOfPinnedObject(); 
    vcpBuffer = (VCP_DATA)Marshal.PtrToStructure(pBuffer, typeof(VCP_DATA)); 
} 
finally 
{ 
    if (handle.IsAllocated) 
     handle.Free(); 
} 
0

首先,ERROR_ITEM []是一個託管數組,因此這不是一個雙向結構。這只是一個管理參考。引用指向的內存有一個同步塊,方法表指針和一個位於實際元素前面的長度說明符。

但是,使用'固定'(https://msdn.microsoft.com/en-us/library/zycewsya.aspxhttps://msdn.microsoft.com/en-us/library/zycewsya.aspx)不會幫助(但檢查我)。爲了避免這個錯誤,由於ERROR_ITEM []具有固定長度,只需用這16個ERROR_ITEM字段替換該數組。您仍然可以對第一個ERROR_ITEMERROR_ITEM*)的地址使用數組語法來訪問後續元素。

或者,只是計算所有16個元素的大小,但只包括第一個作爲一個字段,然後指定在StructLayout屬性爲ERROR_DATASize參數,以便它大到足以容納他們。

此外,當實際的編譯器完全滿意時,Resharper有時會抱怨嵌套的東西。但這是由它作爲一個數組引起的。即使是一個固定不安全的嵌入式數組,也使得C#認爲它在我的經驗中是無法解決的。

+1

感謝您的建議。我相信他們會工作,但我發現了另一種做我需要的方式。 vcpBuffer = new VCP_DATA(); GCHandle handle = GCHandle.Alloc(bytearray,GCHandleType.Pinned); \t try IntPtr pBuffer = handle.AddrOfPinnedObject(); vcpBuffer =(VCP_DATA)Marshal.PtrToStructure(pBuffer,typeof(VCP_DATA)); } finally { if(handle.IsAllocated) handle.Free(); } – Hassan

+0

@Hassan - 你應該做出答案並接受它!這樣做是合理的,並改善了網站。 – hoodaticus