Marshal.SizeOf(typeof(IntPtr)) vs sizeof(IntPtr)

cog*_*el0 4 .net c#

我知道如何从根本上不同的Marshal.SizeOf()sizeof()是。但是在 的情况下,无论 CPU 架构如何,IntPtr它们不会总是返回完全相同的东西吗?

Gle*_*den 6

一方面,有原始类型:

| x64 | x86
| Marshal. | Marshal.
Primitive | SizeOf<T>() sizeof(T) | SizeOf<T>() sizeof(T)
========= | =========== =========== | =========== ===========
Boolean | 4 <-> 1 | 4 <-> 1
Byte | 1 1 | 1 1
SByte | 1 1 | 1 1
Int16 | 2 2 | 2 2
UInt16 | 2 2 | 2 2
Int32 | 4 4 | 4 4
UInt32 | 4 4 | 4 4
Int64 | 8 8 | 8 8
UInt64 | 8 8 | 8 8
IntPtr | 8 8 <-> 4 4
UIntPtr | 8 8 <-> 4 4
Char | 1 <-> 2 | 1 <-> 2
Double | 8 8 | 8 8
Single | 4 4 | 4 4

除此之外,对于.NET 中的struct ( ValueType) 实例,内部托管布局和封送处理图像之间可能存在显着差异,无论是总大小还是字段布局顺序。即使对于所谓的格式化类,后者也是如此。[1]

实际上很少需要有关实际托管结构布局的信息,事实上,.NET不遗余力地试图使其无法被发现。您也无法影响结构的内部布局,这正是该Marshal层提供专门声明互操作所需的任何布局的能力的原因。

这是需要知道结构运行时内存映像的真实大小的一个用例:假设您将结构的托管数组用于某种存储 blob 概念,并且您希望每个块(即数组)保持在一个固定的范围内总分配大小,比如说 ~84,800 字节——显然在这种情况下要远离LOH。您希望这个存储类是一个通用类,用ValueType定义“记录”或表条目的任意类型参数化。要确定可以进入每个托管数组块的结构数,您需要发现在运行时给出的结构的真实大小,因此您可以将 84,800 除以该值。

要更详细地检查封送处理托管内部结构布局、填充和大小之间可能出现的差异,请参阅我对“如何检查结构消耗的字节数? ”的扩展回答



[1.] “格式化类是一种引用类型,其布局由 StructLayoutAttribute 属性指定,如LayoutKind.ExplicitLayoutKind.Sequential。”
https://msdn.microsoft.com/en-us/library/2zhzfk83(v=vs.110).aspx