与元帅相反的行为.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的效果。有人能帮我理解这些相互冲突的行为吗?
对不起,您确实必须考虑技术细节才能理解这些选择。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_t
和char32_t
。然而,在针对Windows的编译器中,它总是16位,因为这是操作系统对字符(又名WCHAR)的选择。它不是在各种Unix风格中,他们喜欢utf8。
在c#中也可以很好地工作,您不会被1字节字符所困扰。. net框架中的每个类型都有一个带有CharSet属性的隐式[StructLayout]属性。默认值是CharSet.Ansi
,与C语言的默认值相匹配。但是,您可以轻松地应用自己的并选择CharSet.Unicode。现在每个字符得到两个字节,使用utf16编码,字符串按原样复制,因为。net也使用utf16。然而,确保本机代码期望该编码中的字符串取决于您。