3

我试图在 AMD64 上从 C#调用NtGetContextThread 。问题是 AMD64 的CONTEXT结构需要在 16 字节边界上对齐,当我调用NtGetContextThread时,我总是得到STATUS_DATATYPE_MISALIGNMENT. 我知道 C# 可以使用Pack属性对齐结构的各个成员,但它似乎无法对齐整个结构。有什么办法可以做到这一点吗?

编辑:为了清楚起见,我不想调整个别成员。我想对齐整个结构。

4

2 回答 2

2

从您的问题来看,尚不清楚您是否完全理解 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 字节边界处对齐。有解决此问题的方法,但您应该注意可能会出现此类问题。

于 2009-08-13T12:50:19.497 回答
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;
于 2013-12-28T13:56:02.423 回答