是否可以在 COM 接口的 C# 实现中指定结构打包大小?
(我知道在托管端定义结构时该怎么做,但我的问题是何时在非托管端定义并在托管端实现。)
我有一个 COM 类型库,它定义了一个结构类型和一个返回这些结构数组的接口方法。我有一个 C# 服务器和一个非托管 C++ 服务器,它们都实现了这个接口,以及一个使用它的 C++ 客户端。C++ 服务器和 C++ 客户端在 32 位构建中都将结构打包为 4 个字节,在 64 位构建中打包为 8 个字节。
但无论平台(x86、x64、AnyCPU)如何,C# 服务器总是打包到 4 个字节。这是正常的吗?它可以被覆盖吗?
该结构如下所示:
typedef [v1_enum] enum { blah... } HandlerPriority;
struct HandlerInfo { BSTR MessageName; HandlerPriority Priority; }
Visual Studio C++ 和 MIDL 编译器使用 /Zp8 的默认打包。在 32 位构建中,结构的两个成员都是 4 字节宽,因此它们没有被填充。在 64 位构建中,字符串指针为 8 个字节,枚举为 4,因此枚举被填充。自然,当 C# 客户端发送未填充的数据时,这会导致问题。
我可以通过指定 /Zp4 删除填充来修复(解决?)问题,并且一切似乎都工作正常。但我想知道这是否是最好的解决方案。
我想默认打包是 /Zp8 仅出于性能原因。据我了解,默认情况下,在 x64 上,硬件会捕获并处理对齐异常,因此至少我们不会崩溃。在这种特殊情况下,我不关心性能损失,因为接口函数只在系统启动时调用。即使我很在意,我仍然可能会接受它作为 COM/.NET 互操作的成本。但我有点不安,因为感觉不对(我想来自 C++ 背景。)
另一方面,如果根本不可能更改托管方的包装,那么我会接受它。
谁能给我一些建议?