2

次の構造体を C# で作成しようとしています。これは C に基づく複雑な構造体です。ほとんどのマーシャリング オプションを試しましたが、常に「System.TypeLoadException」が発生します。

(追加情報: アセンブリ 'WindowsFormsApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' から型 'WindowsFormsApplication1.COMPLEX_STRUCT' を読み込めませんでした。これは、オフセット 8 にオブジェクト フィールドが含まれているためです。 -オブジェクトフィールド。)

IPV6_ADDR 構造体に関して、私は LayoutKind.Explicit と LayoutKind.Sequential の両方を試しました。

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string Addr;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] Addr;

x64 マシンを使用していますが、IPV6_ADDR 構造体が 8 バイトにアラインされているため、何が問題なのかわかりません。

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IPV4_ADDR
{
    public uint Addr;
    public uint SubnetNumBits;
};

[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct IPV6_ADDR
{
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string Addr;
    [FieldOffset(16)]
    public uint SubnetNumBits;
};

[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct COMPLEX_STRUCT
{
    [FieldOffset(0)]
    public byte A;

    [FieldOffset(1)]
    public byte B;

    [FieldOffset(2)]
    public byte C;

    [FieldOffset(3)]
    public byte D;

    [FieldOffset(4)]
    public byte E;

    [FieldOffset(8)]
    public IPV4_ADDR IPv4;

    [FieldOffset(8)]
    public IPV6_ADDR IPv6;

    [FieldOffset(28)]
    public ushort F;
}

私が模倣しようとしている元のC構造体:

typedef struct _IPV4_ADDR
{
    uint32_t Addr;
    uint32_t SubnetNumBits;
} IPV4_ADDR, *PIPV4_ADDR;

typedef struct _IPV6_ADDR
{
    uint8_t  Addr[16];
    uint32_t SubnetNumBits;
} IPV6_ADDR, *PIPV6_ADDR;

typedef struct _COMPLEX_STRUCT
{
    uint8_t A;
    uint8_t B;
    uint8_t C;
    uint8_t D;
    uint8_t E;
    uint8_t Rsvd[3];
    union {
        IPV4_ADDR IPv4;
        IPV6_ADDR IPv6;
    } u;
    uint16_t F;
} COMPLEX_STRUCT, *PCOMPLEX_STRUCT;
4

1 に答える 1

1

元の構造体を見て、IPV4 および IPV6 構造体の他の実装を調べた後、他の実装byte[4]が IPV4 のアドレスを使用していることがわかります。

結果が正しいことを保証することはできませんが、IPV4 と IPV6 の両方をbyte[]代わりに a を使用するように変更できれば、エラーは解消されます。

あなたが見つけたように組み合わせることはできません。私が試すことができる他の唯一のオプションは、それを使用IntPtrしてメモリの場所を取得し、Marshal.Copyを使用してデータを取得できるかどうかを確認することです。

それらが機能するようになったとしても、結果が正しいことを保証することはできません.

于 2014-10-06T21:24:45.993 に答える