Неопределенное поведение с полевым смещением
Я успешно удалил объект структуры из допустимого указателя с помощью функции 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)>