fieldoffset 的未定义行为[重复]

Posted

技术标签:

【中文标题】fieldoffset 的未定义行为[重复]【英文标题】:undefined behaviour with fieldoffset [duplicate] 【发布时间】:2018-01-06 00:35:46 【问题描述】:

我已经使用 PtrToStructure 函数(在 vb.NET 中)从有效指针中成功提取了结构对象,问题是“FrameRects”字段与从 C++ 示例中获得的值相比具有无效值:

vb.NET 代码是:

StructLayout(LayoutKind.Explicit, pack:=1, CharSet:=CharSet.Ansi)> _"

Public Structure myStruct
    <FieldOffset(0)> _
    Dim Width As UInt32 ' 350 correct
    <FieldOffset(4)> _
    Dim Height As UInt32 ' 466 correct
    <FieldOffset(8)> _
    Dim Frames As UInt32 ' 115 correct
    <FieldOffset(12)> _
    Dim FrameNum As UInt32 ' 1 correct
    <FieldOffset(20)> _
    Dim FrameRate As UInt32 ' 15 correct
    <FieldOffset(24)> _
    Dim FrameRateDiv As UInt32 ' 1 correct
    <FieldOffset(28)> _
    Dim ReadError As UInt32 ' 0 correct
    <FieldOffset(32)> _
    Dim OpenFlags As Integer ' 0 correct

    <FieldOffset(16)> _
    <MarshalAs(UnmanagedType.Struct)> _
    Dim FrameRects As RECT ' the problem is located here

    <FieldOffset(36)> _
    Dim NumRects As UInt32 ' 0 correct  

    <FieldOffset(44)> _
    Dim FrameChangePercent As UInt32 ' 0 correct
End Structure

"StructLayout(LayoutKind.Explicit, pack:=1, CharSet:=CharSet.Ansi)> _

Public Structure RECT
    <MarshalAs(UnmanagedType.I4)> _
    <FieldOffset(0)> _
    Dim Left As Integer ' gives me -1 but it must be 0 (in C++ sample)
    <MarshalAs(UnmanagedType.I4)> _
    <FieldOffset(4)> _
    Dim Top As Integer ' gives me 15 but it must be 0 (in C++ sample)
    <MarshalAs(UnmanagedType.I4)> _
    <FieldOffset(8)> _
    Dim Width As Integer ' gives me 1 but it must be 0 (in C++ sample)
    <MarshalAs(UnmanagedType.I4)> _
    <FieldOffset(12)> _
    Dim Height As Integer ' gives me 0 and it is 0 (in C++ sample)
End Structure

C++ 代码是:

 struct myStruct

  U32 Width; // U32 is unsigned integer
  U32 Height;
  U32 Frames;
  U32 FrameNum;
  U32 FrameRate;
  U32 FrameRateDiv;
  U32 ReadError;
  OPEN_FLAGS OpenFlags; // integer
  RECT_ARRAY FrameRects;
  U32 NumRects;
  U32 FrameChangePercent;
;

 struct RECT

  S32 Left; // S32 is singed integer
  S32 Top;
  S32 Width;
  S32 Height;
;

【问题讨论】:

不,它不是任何帖子的完全相同 【参考方案1】:

FrameRate 的字段偏移量不应该是 16,而不是 20?之后的所有内容都向下移动了 4 个字节?直到你到达 FrameRects,它应该是 32?并且由于 FrameRects 是 16 字节,NumRects 应该是 48?

但既然你的结构中的所有内容都是类型化和顺序的,你为什么不使用

<StructLayout(LayoutKind.Sequential)> 

代替

StructLayout(LayoutKind.Explicit, pack:=1, CharSet:=CharSet.Ansi)> 

【讨论】:

它不适用于 LayoutKind.Sequential,如果我使用它,它会给我一个未定义的结果 如果我更改 fieldoffset 的数量,我会得到错误的结果 备注:我无法比较 fieldoffset = 48 的结果和 out_of_boundaries 值,因为它们给出了相同的值(等于 0)。 FrameRects的偏移量是16,是和FrameRate重叠的吧? 帧率不重叠 请帮助_____________?

以上是关于fieldoffset 的未定义行为[重复]的主要内容,如果未能解决你的问题,请参考以下文章

显式结构布局上的未分配字段

何时在空实例上调用成员函数会导致 C++11 中的未定义行为? [复制]

访问静态超出范围的未定义行为吗?

超出数组最大索引的未定义行为

v-for 和自定义组件的未定义行为

int i = f1() * f2() 的未定义行为