我试图在 AMD64 上从 C#调用NtGetContextThread 。问题是 AMD64 的CONTEXT结构需要在 16 字节边界上对齐,当我调用NtGetContextThread时,我总是得到STATUS_DATATYPE_MISALIGNMENT
. 我知道 C# 可以使用Pack属性对齐结构的各个成员,但它似乎无法对齐整个结构。有什么办法可以做到这一点吗?
编辑:为了清楚起见,我不想调整个别成员。我想对齐整个结构。
从您的问题来看,尚不清楚您是否完全理解 StructLayout 属性的 Pack 属性。有关详细信息,请参阅此msdn 文章。
如果我理解正确,那么您正在寻找的是能够单独显式对齐结构的每个成员。如果这是您的目标,您可以使用 StructLayout 和 FieldOffset 属性,如下所示:
[StructLayout(LayoutKind.Explicit)]
public struct Message
{
[FieldOffset(0)]
public int a;
[FieldOffset(4)]
public short b;
[FieldOffset(6)]
public int c;
[FieldOffset(22)] //Leave some empty space just for the heck of it.
public DateTime dt;
}
但请注意,.NET CF Marshaler 有一些您可能不会想到的规则。例如,数组必须始终在 4 字节边界处对齐。有解决此问题的方法,但您应该注意可能会出现此类问题。
我发现这样做的唯一方法是过度分配指针并变得不安全。
像这样:
[StructLayout(LayoutKind.Explicit)]
struct Foo
{
/* fields go here */
}
var ptrMemory = Marshal.AllocHGlobal(sizeof(Foo) + 64);
IntPtr ptrAligned = new IntPtr(64 * (((long)ptrMemory + 63) / 64));
MyStructPointer* Foo = (Foo*)ptrAligned;