[英]How to properly marshal unmanaged arrays in c# without unsafe
我有非托管結構:
typedef struct
{
char a[48];
BYTE b;
BYTE c;
BYTE d;
BYTE e;
BYTE f;
BYTE x;
char y[32];
char z[128][32];
}SOMELIKE_STRUCT
我嘗試編組它,因為它是在StackOverflow中的另一個線程中編寫的:
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct SOMELIKE_STRUCT
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 48)]
public byte[] a;
[FieldOffset(48)]
public byte b;
[FieldOffset(49)]
public byte c;
[FieldOffset(50)]
public byte d;
[FieldOffset(51)]
public byte e;
[FieldOffset(52)]
public byte f;
[FieldOffset(53)]
public byte x;
[FieldOffset(54)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.U1, SizeConst = 32)]
public byte[] y;
[FieldOffset(86)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.Struct, SizeConst = 128)]
public STRUCT[] z;
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct STRUCT
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32)]
public byte[] name;
}
我有例外:
System.TypeLoadException未處理附加信息:無法從程序集'ConsoleApplication2,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'加載類型'SOMELIKE_STRUCT',因為它包含偏移'54'處的對象字段,該字段未正確對齊或由非對象字段重疊。
當我使用new創建此結構時,會顯示異常:
SOMELIKE_STRUCT l = new SOMELIKE_STRUCT();
異常顯示我何時使用該結構創建類(當進入構造函數時)(在創建該結構的實例之前)
由於你的定義似乎是正確的,所以無法弄清楚這里發生了什么。
將布局更改為順序並刪除手動字段偏移似乎有效:
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public struct SOMELIKE_STRUCT
{
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 48 )]
public byte[] a;
public byte b;
public byte c;
public byte d;
public byte e;
public byte f;
public byte x;
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32 )]
public byte[] y;
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 128 )]
public STRUCT[] z;
}
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
public struct STRUCT
{
[MarshalAs( UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 32 )]
public byte[] name;
}
使用Marshal.SizeOf
檢查大小會產生4182個字節,並使用Marshal.OffsetOf
檢查生成的布局會提供與原始代碼相同的偏移量。 我相信這里的其他人可以詳細說明為什么會這樣。
struct中包含的結構和表必須放在字的倍數地址(x86 / x64為4/8字節)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.