C++;指定结构的实际大小 我遇到了一个C语言和C++之间的互操作问题,我通过在本地和托管代码中定义的结构来在应用程序的两个“边”之间共享内存。本机端的结构定义如下: #pragma pack(push, 1) struct RayTestCollisionDesc { btVector3 hitPosition; btRigidBody* hitBody; RayTestCollisionDesc(btRigidBody* body, btVector3& position) : hitBody(body), hitPosition(position) { } }; #pragma pack(pop)

C++;指定结构的实际大小 我遇到了一个C语言和C++之间的互操作问题,我通过在本地和托管代码中定义的结构来在应用程序的两个“边”之间共享内存。本机端的结构定义如下: #pragma pack(push, 1) struct RayTestCollisionDesc { btVector3 hitPosition; btRigidBody* hitBody; RayTestCollisionDesc(btRigidBody* body, btVector3& position) : hitBody(body), hitPosition(position) { } }; #pragma pack(pop),c++,struct,sizeof,memory-alignment,packing,C++,Struct,Sizeof,Memory Alignment,Packing,在托管(C#)端定义了一个类似的结构。在C#上,结构大小为20字节(正如我在32位系统上所期望的那样)。但是,尽管 PrimaPosib指令,C++大小的结构大小仍然是32。为了清晰起见,C++的每种类型都有< siZoF()/Cuth>: sizeof(btVector3) : 16 sizeof(btRigidBody*) : 4 sizeof(RayTestCollisionDesc) : 32 显然,pragma pack仅指结构成员之间的打包,而不是结构末尾的填充(即对齐)。我还

在托管(C#)端定义了一个类似的结构。在C#上,结构大小为20字节(正如我在32位系统上所期望的那样)。但是,尽管 PrimaPosib指令,C++大小的结构大小仍然是32。为了清晰起见,C++的每种类型都有< <代码> siZoF()/Cuth>:

sizeof(btVector3) : 16 
sizeof(btRigidBody*) : 4
sizeof(RayTestCollisionDesc) : 32
显然,
pragma pack
仅指结构成员之间的打包,而不是结构末尾的填充(即对齐)。我还尝试添加了
\uuudeclspec(align(1))
,但没有效果,MSDN本身也说“uuudeclspec(align(#))只能增加对齐限制。”

FWIW我正在使用VS2013编译器(平台工具集v120)


有没有办法将结构大小“强制”为20字节?

您正在两个不同的编译器之间传输数据。一般来说,这是不可能匹配的。尤其是当你将数据从一台计算机传输到另一台计算机时

首先为正在传输的数据编写规范。规范不能是C++或C结构。规范必须类似于“四个字节这个,四个字节那个,两个字节第三件事…”等等,“总共20个字节”,例如

然后,无论你使用C++还是C语言,或者完全不同的开发人员使用Objto-C代码来读取数据,你都会读取一个20字节的数组,取20字节,看它们,用这20个字节填充你想要的任何结构。而对于写作,你做的恰恰相反。现在,C++编译器使用什么,你使用的奇怪的语法,它只是工作。p>


或者使用一些可移植的东西,比如JSON

您不能用这种方式进行互操作。一个C对象和一个C++结构是不同的。我建议您使用一个序列化库,比如Capt'n Proto或Protobuf

btVector3
可能在16字节边界对齐,以启用SSE内部函数。如何添加显式填充,使结构始终为32字节?也许问题出在C#端?我对此一无所知,但从问题的数量来看,似乎很容易出错。这一个看起来是一个很好的答案:@Jens这个问题的答案几乎就是我实现的(两边的packing都设置为1)。根据我的预期,C端是“正确的”(即20字节,没有开销)。然而,我认为上面的Bo Persson可能已经找到了编译器拒绝对齐结构的原因;因为btVector3确实支持SSE。嗨,纪尧姆,谢谢你的回复。不幸的是,在这种情况下,我认为这不是一个可行的解决方案——我之所以以这种方式共享内存,首先是出于性能原因。如果我可以轻松地序列化数据,那么无论如何,我只需要通过P/Invoke。我知道Protobuf和Capt'n Proto速度非常快,但最终它们将是不必要的开销,我认为gnasher的答案更合适;PInvoke及其所提供的属性正好支持这种场景,Win32 C++编译器除了标准所要求的与系统API和COM ABI的互操作性之外,还有其他的保证;大多数Win32.NET管道都是通过PInvoke完成的,非平凡的
struct
通常通过使用适当的PInvoke声明进行透明封送。