与元帅相反的行为.c#中布尔和char数据类型的SizeOf和SizeOf操作符

本文关键字:SizeOf 布尔 数据类型 操作符 char | 更新日期: 2023-09-27 18:02:29

我在c#中比较Marshal.SizeOf API与sizeof运算符。它们对于char和bool数据类型的输出并不令人惊讶。以下是结果:

对布尔

:

元帅。SizeOf = 4

size = 1

对字符

:

元帅。SizeOf = 1

size = 2

在这个来自MSDN的链接上,我得到了以下文本:

对于所有其他类型,包括结构体,sizeof操作符可以为仅在不安全代码块中使用。虽然你可以用元帅。SizeOf方法,此方法返回的值并不总是与sizeof返回的值相同。元帅。SizeOf返回类型被封送后返回Size,而sizeof返回由公共语言运行库分配的大小,

我不太了解封送的技术细节,但是当事情发生变化时,它与运行时启发式有关。按照bool的逻辑,大小从1变化到4。但对于char(从2到1),它正好相反,这对我来说是一个回旋镖。我认为char也应该增加bool的效果。有人能帮我理解这些相互冲突的行为吗?

与元帅相反的行为.c#中布尔和char数据类型的SizeOf和SizeOf操作符

对不起,您确实必须考虑技术细节才能理解这些选择。pinvoke的目标语言是C语言,按照现代标准,这是一种非常古老的语言,具有许多的历史,并用于不同机器体系结构的许多。它对类型的大小做了很少的假设,字节的概念不存在。这使得这种语言很容易移植到C语言发明时常见的机器上,以及超级计算机和数字信号处理器中使用的不寻常的体系结构上。

C本来没有bool类型。逻辑表达式使用int,其中值0表示false,任何其他值表示true。在winapi中,它也使用BOOL类型,这是int的别名。所以选4是合乎逻辑的。但这不是一个普遍的选择,你必须小心,许多c++实现使用单个字节,COM Automation选择两个字节。

C确实有一个char类型,唯一的保证是它至少有8位。无论它是有符号的还是无符号的,目前大多数实现都使用有符号的。对8位字节的支持在今天可以执行托管代码的体系结构中是普遍的,所以char在实践中总是8位。所以1是合乎逻辑的选择。

这不会让你高兴,没有人会对此感到高兴,你不能支持用任意语言用8位字符类型编写的文本。Unicode通过使用许多可能的8位编码来解决这个灾难,但它对C和c++语言没有太大影响。他们的委员会确实在标准中增加了wchar_t(宽字符),但按照过去的做法,他们没有确定其大小。这使得它毫无用处,迫使c++后来添加char16_tchar32_t。然而,在针对Windows的编译器中,它总是16位,因为这是操作系统对字符(又名WCHAR)的选择。它不是在各种Unix风格中,他们喜欢utf8。

在c#中也可以很好地工作,您不会被1字节字符所困扰。. net框架中的每个类型都有一个带有CharSet属性的隐式[StructLayout]属性。默认值是CharSet.Ansi,与C语言的默认值相匹配。但是,您可以轻松地应用自己的并选择CharSet.Unicode。现在每个字符得到两个字节,使用utf16编码,字符串按原样复制,因为。net也使用utf16。然而,确保本机代码期望该编码中的字符串取决于您。