导出的 C 函数与结构与 .Net 编组中的布尔大小

Posted

技术标签:

【中文标题】导出的 C 函数与结构与 .Net 编组中的布尔大小【英文标题】:Size of bool in exported C function vs struct vs .Net marshaling 【发布时间】:2012-10-31 16:00:12 【问题描述】:

我不确定这是否是个问题,但肯定是出于好奇。我有一个 C DLL,它导出一个采用 32 位整数和一个布尔值 (stdbool.h) 的函数。导出的函数(stdcall)表示参数列表为8字节(4字节int,4字节bool)。此 C DLL 还包含一个使用布尔值的结构。检查 sizeof(bool) 表示 1 字节布尔值。

我有一个用于本机 DLL 的 .Net 包装器。在编组结构时,我为每个布尔字段 UnmanagedType.U1 指定并且一切正常,一切都正确对齐。我只使用了顺序布局,没有显式,也没有任何偏移,也没有任何包装。

我的问题是,为什么布尔大小有明显的差异?

【问题讨论】:

DLL 是用什么编译器制作的? 【参考方案1】:

C 中所有小于“int”的函数参数在调用中都转换为“int”大小。这是因为每个参数都是单独放置在堆栈上的(在大多数架构中),因此它们被转换为堆栈单元大小,通常等于“int”的大小。

至于结构 - 没有任何转换。尽管我们不应该忘记结构中的对齐。但这是另一回事了。

【讨论】:

该语言不需要这个,尽管许多实现可能。 @KeithThompson 如果缺少函数原型,该语言确实需要它。然后发生默认参数提升,将所有小整数提升为 int。虽然在这种特定情况下是否缺少原型,但我们不知道。 @Lundin 是的,这种情况下存在原型。 @Lundin:默认参数提升不会发生“因为每个参数都分别放在堆栈上”(尽管它们可能是出于类似的动机)。 我同意 Keith Thompson 的观点,但我不认为我们的陈述相互矛盾。是的,语言不需要,但正如我所说 - “在大多数架构中”。说“架构”,我的意思是编译器“实现”,这对应于 Keith Thompson 的回复。

以上是关于导出的 C 函数与结构与 .Net 编组中的布尔大小的主要内容,如果未能解决你的问题,请参考以下文章

用于 C 结构和函数的 C# 编组

从 WM_COPYDATA 消息编组结构

如何编组从 C 头文件中的宏定义的结构?

C++ 到 C# 回调结构编组

C# Struct 到字节数组的编组方式与 Delphi 中的打包记录相同

将 C++ 类编组为结构