ro0*_*ter 6 c# c++ 64-bit callback memory-alignment
由于我之前的问题没有成功(" 使用x86/x64 C API的C#AnyCPU库 - 打包结构,调用和回调 "),我将编写一个更简洁和抽象的问题.
图片:
我工作的公司有一个64位移植的软件.该软件包含一个BASE库(带有C API的C++)和C API上的两个包装器:一个C++包装器和一个.NET包装器.
C++ BASE库和C++ WRAPPER应该具有x86/x64构建配置..NET WRAPPER应该只有AnyCPU构建配置.
从.NET WRAPPER中选择正确的库已经成功完成(两个C++ BASE库(x86/x64)都被加载到两个独立的命名空间中,并且根据IntPtr的大小,在运行时调用正确的函数;这不一定需要两个库都在那里,但只有一个被使用).
问题:
BASE库中的所有结构都以4个字节对齐:
#pragma pack(push,4)
Run Code Online (Sandbox Code Playgroud)
为了让代码在64位上没有警告编译,我添加了选择性对齐(C++ BASE和C++ WRAPPER工作,如魅力):
#ifdef WIN64
#pragma pack(push,8)
#else
#pragma pack(push,4)
#endif
Run Code Online (Sandbox Code Playgroud)
问题与.NET中的结构有关:
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
internal struct DBConnectionSettings{...}
Run Code Online (Sandbox Code Playgroud)
由于AnyCPU是唯一需要的WRAPPER配置,因此该结构不能具有选择性打包.
在不同的.NET命名空间中创建在8个字节上对齐的单独结构是非常困难的(很多和很多的PEFRORMANCE LOSS)...... 然而,这可能是我们可能完全正常工作的唯一解决方案.
回归到x86和x64的4字节对齐问题很多警告,因为100%的结构对打包敏感,特别是对于一元运算符(问题仅出现在x64解决方案配置上,对齐4字节).很多崩溃,除非我们添加虚拟成员,否则结构无法对齐.我应该提一下,结构是基于含义或与许可证/目标OS(ifdefs)相关的分组.为所有可能性添加填充(虚拟)成员需要数月.
将8个字节上的所有内容对齐都不是解决方案,因为我们再次崩溃整个地方 - 仅对于x86,x64工作得很好 - 结构对齐需要再次使用虚拟(填充)成员并根据大小进行分组.
结论(问题):
1)对于x86和x64解决方案配置,C++代码是否可以对齐4?如何实现这一目标?
2)x86和x64对齐的最佳替代方案是什么?指针大小肯定应该统一对齐(在我看来).我们正在寻求拥有FAST软件,不一定具有内存效率(到目前为止,x86系统上的内存指纹介于15mb和2gb之间).
3)对于.NET和C之间的互操作,带有函数指针的结构有什么特殊需求?
4)高度赞赏任何建议的替代方案.
我们一直在这个互联网上搜索一个多月(我们星球上的那个),但我们无处可去.一些建筑师恳求使用选择性打包(4/8),而有些人认为软件不是直截了当的,应该重构.这不是我的决定该做什么,但我可以提出有充分理由的想法.该软件已于2000年末启动,当时STL出现故障,因此BASE有自己的容器,专门针对上帝知道什么.我不应该在这里表达我的意见,因为它不是基督徒.
只需修复C++端的对齐问题即可。x86 代码应该没有理由在 8 字节对齐时崩溃,x64 也不应该在 4 字节对齐时崩溃。#pragma pack(push,4)将是一个合适的方法。您可能需要另一个#pragma pack用于内部 SSE 代码,但该代码不应暴露给 .Net AnyCPU 代码。
如果您收到数百个警告(当然忽略性能警告),那么编译器同意我的评估,即您的代码是可疑的。
| 归档时间: |
|
| 查看次数: |
779 次 |
| 最近记录: |