Pertanyaan Disejajarkan atau tumpang tindih secara salah dengan kesalahan bidang non-objek


Saya mencoba membuat struktur berikut:

    [StructLayout(LayoutKind.Explicit, Size=14)]
    public struct Message
    {
        [FieldOffset(0)]
        public ushort X;
        [FieldOffset(2)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]
        private ushort[] Y;
        [FieldOffset(12)]
        public ushort Z;
    }

dan saya mendapatkan kesalahan berikut:

Tidak dapat memuat tipe 'Pesan' dari perakitan karena berisi bidang objek pada offset 4 yang salah disejajarkan atau tumpang tindih dengan bidang non-objek.

Apakah ada yang tahu mengapa ini menyebabkan kesalahan?

Catatan: Saya tidak dapat menggunakan Paket karena saya bekerja dengan kerangka kerja yang ringkas. Terima kasih.


9
2017-07-27 19:20


asal


Jawaban:


CF Marshaler tidak begitu bagus dalam hal semacam ini dan apa yang Anda coba tidak didukung. Masalahnya adalah ia tahu bahwa elemen pertama tidak sejajar, tetapi tampaknya tidak mengerti bahwa setiap elemen dalam array juga tidak akan sejajar.

Anda dapat melihat perilaku bekerja dalam contoh ini:

[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
    [FieldOffset(0)]
    public ushort X;

    [FieldOffset(2)]
    private ushort Y1;

    [MarshalAs(UnmanagedType.LPArray)]
    [FieldOffset(4)]
    private ushort[] Y2;

    [FieldOffset(12)]
    public ushort Z;
}

Untuk tipe struktur seperti ini, saya tidak pernah membiarkan marshaler mencoba menangani setiap anggota. Strukturnya kecil, jadi pisahkan setiap barang seperti ini:

[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
    [FieldOffset(0)]
    public ushort X;

    [FieldOffset(2)]
    private ushort Y1;

    [FieldOffset(4)]
    private ushort Y2;

    [FieldOffset(6)]
    private ushort Y3;

    [FieldOffset(8)]
    private ushort Y4;

    [FieldOffset(10)]
    private ushort Y5;

    [FieldOffset(12)]
    public ushort Z;
}

atau gunakan "serikat" simulasi seperti ini:

public struct Y
{
    public ushort a;
    public ushort b;
    public ushort c;
    public ushort d;
    public ushort e;
}

[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
    [FieldOffset(0)]
    public ushort X;

    [FieldOffset(2)]
    private Y Y;

    [FieldOffset(12)]
    public ushort Z;
}

8
2017-07-27 20:24



Masalahnya terjadi karena array Anda tumpang tindih "X". ulong, dalam C #, adalah UInt64 (dalam C ++, ulong adalah UInt32), jadi sebenarnya 8 byte.

Jika Anda mengubah FieldOffset kedua menjadi 8, atau mengubah X menjadi uint, ini akan hilang.


1
2017-07-27 19:24