2

我正在尝试在这篇msdn文章中创建以下结构。我正在尝试学习整个 FieldOffset 但不知道从哪里开始。

我基本上做了这样的事情。

[StructLayout(LayoutKind.Explicit, Size=12)]
public struct DHCP_OPTION_DATA_ELEMENT {
    [FieldOffset(0)]
    public DHCP_OPTION_DATA_TYPE OptionType;
    [FieldOffset(4)]
    public byte ByteOption;
    [FieldOffset(4)]
    public uint WordOption;
    [FieldOffset(4)]
    public UInt32 DWordOption;
    [FieldOffset(4)]
    public UInt32 DWordDWordOption;
    [FieldOffset(4)]
    public uint IpAddressOption;
    [FieldOffset(4)]
    public IntPtr StringDataOption;
    [FieldOffset(4)]
    public DHCP_BINARY_DATA BinaryDataOption;
    [FieldOffset(4)]
    public DHCP_BINARY_DATA EncapsulatedDataOption;
    [FieldOffset(4)]
    public string Ipv6AddressDataOption;
}

但是,它向我咆哮,说明了以下例外。

it contains an object field at offset 4 that is incorrectly aligned or 
overlapped by a non-object field.
4

3 回答 3

2

将其视为 IntPtr,而不是字符串。

但是,在使用 IntPtr 时,请务必注意自己进行清理,因为您现在将使用非托管内存,因此 GC 不会帮助您,每次通过时都会导致内存泄漏这个结构。

正如 shf301 在另一个答案中所建议的那样,您很可能会想要使用 Marshal.PtrToStringUni 函数。

于 2012-11-28T06:56:22.260 回答
1

错误

它包含偏移量 4 处的对象字段,该对象字段未正确对齐或被非对象字段重叠。

是由于将非对象 ( blittable ) 类型 (eg Uint32) 与对象类型 (non-blittable ) 重叠。编组器无法处理。marhshaler 不知道联合的哪个字段是有效的(因为它不知道如何解码OptionType,所以它不知道是否应该编组字符串值或整数值。尝试将整数值编组为字符串会导致崩溃(因为整数值不会指向有效的字符串),所以编组器抛出异常而不是让你崩溃。

因此,您必须通过将字符串定义为IntPtr's 并使用Marshal.PtrToStringUni()Marshal.PtrToStringAnsi()来手动编组字符串。

您可能对 DHCP_BINARY_DATA 也有同样的问题。

于 2012-11-28T07:15:07.380 回答
0

你有这个代码:

[FieldOffset(4)]
public string Ipv6AddressDataOption;

字符串是引用类型(对象),其他字段是值类型(非对象)。因此,您必须更改Ipv6AddressDataOption.

于 2012-11-28T05:50:18.323 回答