簡體   English   中英

如何正確編組c#中的非托管數組而不安全

[英]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'處的對象字段,該字段未正確對齊或由非對象字段重疊。

  1. 當我使用new創建此結構時,會顯示異常:

    SOMELIKE_STRUCT l = new SOMELIKE_STRUCT();

  2. 異常顯示我何時使用該結構創建類(當進入構造函數時)(在創建該結構的實例之前)

由於你的定義似乎是正確的,所以無法弄清楚這里發生了什么。

將布局更改為順序並刪除手動字段偏移似乎有效:

[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM