我正试图在AMD64上从C#调用 NtGetContextThread 。问题是AMD64的 CONTEXT 结构需要在16字节边界上对齐,当我调用 NtGetContextThread 时,我总是得到STATUS_DATATYPE_MISALIGNMENT
。我知道C#可以使用 Pack 属性对齐结构的各个成员,但它似乎无法对齐整个结构。我有什么方法可以做到这一点吗?
编辑:为了说清楚,我不想让个别成员对齐。我想对齐整个结构。
答案 0 :(得分:2)
从您的问题来看,您是否完全理解StructLayout属性的Pack属性尚不清楚。有关详细信息,请参阅此msdn article。
如果我理解正确,那么您正在寻找的是能够单独显式地对齐结构的每个成员。如果这是您的目标,您可以使用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字节边界对齐。这个问题有workarounds,但你应该知道这样的问题可能会出现。
答案 1 :(得分:0)
我发现这样做的唯一方法是过度分配指针并变得不安全。
像这样:
[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;