C# 我们可以对结构布局进行假设吗?

C# 我们可以对结构布局进行假设吗?,c#,c,compiler-construction,interop,struct,C#,C,Compiler Construction,Interop,Struct,在C上进行结构布局所使用的算法有什么约定吗 我希望能够让一个代码在vm中运行,使其结构与C对应的代码兼容,就像C#interop工作一样。为此,我需要知道对齐算法是如何工作的。我想这一定有一个对流,因为它在C#上工作得很好。我想到了他们用来解决这个问题的可能算法,但我没有找到任何证据证明它是正确的 以下是我认为它的工作原理: 对于每个声明的字段(按声明顺序) 查看字段是否适合剩余字节(直到下一次对齐) 如果不合适,请对齐此字段;否则,将其添加到当前偏移 例如,在结构的32位系统上,例如: {

在C上进行结构布局所使用的算法有什么约定吗

我希望能够让一个代码在vm中运行,使其结构与C对应的代码兼容,就像C#interop工作一样。为此,我需要知道对齐算法是如何工作的。我想这一定有一个对流,因为它在C#上工作得很好。我想到了他们用来解决这个问题的可能算法,但我没有找到任何证据证明它是正确的

以下是我认为它的工作原理:

对于每个声明的字段(按声明顺序)

  • 查看字段是否适合剩余字节(直到下一次对齐)
  • 如果不合适,请对齐此字段;否则,将其添加到当前偏移
例如,在结构的32位系统上,例如:

{
byte b1;
byte b2;
int32 i1;
byte b3;
}
使用此算法时会是这样:

{
byte b1;
byte b2;
byte[2] align1;
int32 i1;
byte b3;
byte[3] align2;
}

通常,C中的结构对齐取决于所使用的编译器,尤其是在处理结构声明时有效的编译器选项。你不能做任何一般性的假设,除了说对于用特定设置编译的特定程序中的特定结构,可以确定结构布局


也就是说,您的猜测与大多数编译器使用默认对齐设置时可能会做的事情非常吻合。

还值得指出的是,编译器通常有一种方法来指定压缩结构,即完全不填充。我想不出我在PC上使用过的任何一个编译器都没有办法做到这一点(如果不手动将其填充到有效的对齐方式,可能会影响性能)。这是真的。压缩结构几乎总是可用的,但几乎从来都不是默认的。这很公平!我对c编译器的标准化行为期望过高!但是很高兴知道我所画的算法是默认的,这应该足够了(C#的InteropService应该以同样的方式工作,并且它们提供了一种明确定义偏移量的方法)。非常感谢。压缩结构的问题比你想象的要多得多。我会把它们从根本上排除在外。例如,即使
x
foo
中类型为
int
的元素,
&foo.x
也可能不是有效的
int*
您可以传递到其他函数@Waneck:对于同一ABI,它完全是任意两个编译器之间的标准(对于同一ISA(指令集体系结构)的任意两个编译器,它几乎肯定是相同的)。在任何情况下,在现实世界中,算法将始终与我链接到的答案(作为对问题的评论)中所描述的完全相同。我建议在这里阅读我的答案:实际上,该答案与大小有关,而不是偏移量,但算法也很容易确定偏移量。@R。。哇!非常好的回答!!你应该把它作为答案贴在这里,因为它确实更精确。不过,有一个问题,当你说类型的对齐方式为round时,你的意思是,例如,如果你的示例中有一个短b而不是int b,那么它将对齐到偏移量2,而不是1?