简体   繁体   English

如何在 C# 中创建这个结构?

[英]How can I create this struct in C#?

I am trying to create the following struct in this msdn article.我正在尝试在这篇msdn文章中创建以下结构。 I am trying to learn the whole FieldOffset but have no clue where to start.我正在尝试学习整个 FieldOffset 但不知道从哪里开始。

I basically did something like this.我基本上做了这样的事情。

[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;
}

However, it barked at me stating the following exception.但是,它对我咆哮,说明以下异常。

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

Treat it as an IntPtr, instead of a string.将其视为 IntPtr,而不是字符串。

However, when using an IntPtr, be darn sure you take care of cleaning up after yourself, because you will now be working with unmanaged memory and thus the GC won't be helping you out, leading to a nice memory leak each time you pass this struct around.但是,当使用 IntPtr 时,请务必确保您自己进行清理,因为您现在将使用非托管内存,因此 GC 不会帮助您,每次通过时都会导致内存泄漏这个结构周围。

You're going to want to be using the Marshal.PtrToStringUni function, most likely, as suggested by shf301 in another answer.您很可能希望使用 Marshal.PtrToStringUni 函数,正如 shf301 在另一个答案中所建议的那样。

The error错误

it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.它包含偏移 4 处的对象字段,该对象字段未正确对齐或与非对象字段重叠。

Is due to overlapping a non-object ( blittable ) type (eg Uint32 ) with an object type (non-blittable).是由于非对象(重叠blittable )类型(例如Uint32 )与对象类型(非blittable)。 The marshaler cannot handle that.封送拆收器无法处理。 The marhshaler doesn't know which field of the union is valid (since it doesn't know how to decode OptionType so it doesn't know if it should marshal a string value or an integer value. Trying to marshal an integer value to a string would lead to a crash (since an integer value won't point to a valid string), so the marshaller throws the exception instead of allowing you to crash. marhshaler 不知道联合的哪个字段是有效的(因为它不知道如何解码OptionType所以它不知道它是否应该编组字符串值或整数值。试图将整数值编组为string 会导致崩溃(因为整数值不会指向有效的字符串),因此编组器会抛出异常而不是让您崩溃。

So you have to marshal the strings manually by defining them as IntPtr 's and using Marshal.PtrToStringUni() or Marshal.PtrToStringAnsi() .因此,您必须通过将字符串定义为IntPtr并使用Marshal.PtrToStringUni()Marshal.PtrToStringAnsi()来手动编组字符串。

You may have the same issue with DHCP_BINARY_DATA as well.您也可能对 DHCP_BINARY_DATA 有同样的问题。

You have this code:你有这个代码:

[FieldOffset(4)]
public string Ipv6AddressDataOption;

String is reference type (object), and other fields are value type (non-object).字符串为引用类型(对象),其他字段为值类型(非对象)。 So you have to change the Offset for the Ipv6AddressDataOption .所以你必须改变Ipv6AddressDataOption的偏移Ipv6AddressDataOption

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM