我有一个这样的结构
[StructLayout(LayoutKind.Sequential)]
internal struct Context
{
internal uint ContextFlags;
private readonly IntPtr Dr0;
private readonly IntPtr Dr1;
private readonly IntPtr Dr2;
private readonly IntPtr Dr3;
private readonly IntPtr Dr6;
private readonly IntPtr Dr7;
private readonly FloatingSaveArea FloatingSave;
private readonly IntPtr SegGs;
private readonly IntPtr SegFs;
private readonly IntPtr SegEs;
private readonly IntPtr SegDs;
private readonly IntPtr Edi;
private readonly IntPtr Esi;
private readonly IntPtr Ebx;
private readonly IntPtr Edx;
private readonly IntPtr Ecx;
private readonly IntPtr Eax;
private readonly IntPtr Ebp;
internal IntPtr Eip;
private readonly IntPtr SegCs;
private readonly IntPtr EFlags;
private readonly IntPtr Esp;
private readonly IntPtr SegSs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
private readonly byte[] ExtendedRegisters;
}
使用以下pinvoke方法填充数据
[DllImport("kernel32.dll")]
internal static extern bool GetThreadContext(IntPtr hThread, ref Context lpContext);
我只需要访问变量ContextFlags
和Eip
理想情况下,我想从不需要的结构中删除所有其他变量,但是,当我这样做时,Eip
变量将不再填充正确的值。
我也尝试了以下方法
[StructLayout(LayoutKind.Explicit)]
internal struct Context
{
[FieldOffset(0)]
internal uint ContextFlags;
[FieldOffset(184)]
internal IntPtr Eip;
}
字段偏移量184来自
uint offsetEip = (uint) Marshal.OffsetOf(typeof(Context), "Eip");
这也不起作用
有没有办法做到这一点?也许通过使用类而不是结构?
答案 0 :(得分:1)
它当然可以工作,最后,它只是一个不透明的字节数组,但是您必须确保整个结构大小相同并且匹配当前的硬件/软件上下文,因此,只需为x86进程定义如下:
[StructLayout(LayoutKind.Explicit, Size = 716)] // size is 716 for x86
internal struct X86Context
{
[FieldOffset(0)]
internal uint ContextFlags;
[FieldOffset(184)]
internal IntPtr Eip;
}
答案 1 :(得分:0)
该结构在Windows头文件中定义,以与Windows API函数相对应,并且假定您将地址传递给与完整结构相同大小的已分配/拥有的内存位置。由于Windows API函数仅获得一个指针,因此尽管您将只使用其中两个成员,但它必须假定您已将指针传递给整个结构。您可以创建自己的相同大小的结构,以仅显示所需的两个成员。