Marshal.SizeOf和sizeof的区别

C# sizeof 关键字的使用 阅读详情

Sizeof在非Unsafe环境下只能用于预定义的一系列类型,如Int,Short等等。而在Unsafe环境下,sizeof可以被用于值类型,但是值类型中不可以有引用类型,否则C#编译器会报错:

error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('SizeOf.Program.MyStruct')

而Marshal.SizeOf则是获得该类型被Marshal(转换,通常翻译为列集,指数据从一种类型转换到另外一种类型)到对应的非托管类型的大小。和sizeof不同,Marshal.SizeOf允许用在含有引用类型的值类型上:

   1: [StructLayout(LayoutKind.Sequential)]
   2: struct MyStruct
   3: {
   4:     string s;
   5: }

Marshal.SizeOf(MyStruct)结果为4或者8,因为string被Marshal成char*。

如果用在不含有引用类型的值类型上,其结果也有可能和sizeof完全不一样,如对于下面的值类型:

   1: struct MyStruct
   2: {
   3:     char b;
   4: }

sizeof(MyStruct)为2,而Marshal.SizeOf(typeof(MyStruct))结果则为1。这是因为在.NET中char总是Unicode,而缺省情况下char会被Marshal成8位的Ansi字符,因此结果不同。

反之,如果我们指定这个char被Marshal成short值(也就是UTF16),如下:

   1: [StructLayout(LayoutKind.Sequential)]
   2: struct MyStruct
   3: {
   4:     [MarshalAs(UnmanagedType.I2)]
   5:     char b;
   6: }

那么sizeof和Marshal.SizeOf结果均为2。MarshalAs这个Attribute可以影响Marshal.SizeOf的结果,而不能影响sizeof的结果。

一个有意思的情况是,如果值类型不含任何成员,如下:

   1: struct MyStruct
   2: {
   3: }

Sizeof和Marshal.SizeOf结果均为1,而不是0。这个结果和C++的结果是一致的。原因很简单:如果声明一个这样的数组,如果元素大小为0的话,那么每个元素都具有相同的地址,这是不为C++标准所允许的,和正常的非0的情况也不一致。.NET在这里采用和c++相同的规则,也认为空的值类型大小为1。

最后需要注意的是,如果MyStruct是模板:

   1: struct MyStruct
   2: {
   3:     T a;
   4: }

如果对Marshal.SizeOf传入MyStruct<>或者MyStruct这样的类型,则抛出ArgumentException,因为Marshal.SizeOf完全不支持泛型。这个是历史遗留问题,从本质上来讲实例化的模板类型(MyStruct)应该是支持的,据说当时主要是没有时间加上对模板的支持。

同样的,sizeof也不支持模板类型,而且连MyStruct这样子的类型也不支持。C#编译器会对sizeof(MyStruct)报错:error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('SizeOf.Program.MyStruct')


作者:张羿
转载请注明出处

Aras Innovator系统配置-01对象类(一) 对象类配置-对象类属性说明 阅读详情

相关推荐

Windows10检查Cuda和cuDNN是否安装成功?

简介:根据上篇博客已经完成了CUDA和cuDNN的安装步骤,完成对其的安装。下面将来检查它们是否安装成功。 1 .首先win+R进入CMD,在命令行输入nvcc -V,如下图所示,则表示cuda已经安装成功。 2 .进入到cuda的安装路径,C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\extras\demo_suite,找到如下两个.exe文件: 首先执行:deviceQuery.exe,查看是否出现如下界面: 然后执行bandwid

jhsignal的博客 14万+

C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)

C# 能否获取一个对象所占内存的大小? 今日,在项目重构的时候忽然想到一个问题,一个类哪些成员的增加,会影响一个类所占内存的大小?C#有没有办法知道一个对象占多少内存呢? 第一个问题:很快想到的是类的非静态的字段,属性; 第二个问题:首先想到的是 sizeof()。 下面开始验证,首先来验证值类型,验证代码如下: int size = sizeof (int); //4个字节 注意点:sizeof 运算符仅适用于值类型,而不适用于引用类型。sizeof 运算符只能在不安全代码块中使用。如下面的代码将

qq_33869036的博客 1590

Python xlwings报错解决:从‘NoneType‘到完美运行WPS表格的完整指南

本文深入解析了使用Python xlwings库自动化WPS表格时遇到的经典'NoneType'报错(AttributeError: 'NoneType' object has no attribute 'apps')的根源与解决方案。核心在于pywin32版本与WPS的兼容性问题,文章提供了从版本降级、依赖管理到构建健壮自动化环境的完整实战指南,帮助开发者彻底解决兼容性难题,实现稳定运行。

n4o5p6q7r的博客 301

C# Marshal.SizeOf和sizeof的区别

今天在C#的程序中导入C++的dll时,发现C++中结构体里的bool类型变量是用的BOOL,在C++头文件中定义的是int为BOOL,占4个字节。C#中相应的结构体里用的却是bool类型,可是bool类型只占一个字节,于是我就产生了疑问,为什么这样不会导致结构体所占的字节大小不同呢? 这是因为我们在封装定义结构体时,是非托管代码。我们在C#中直接sizeof(bool),得到的是1字节,但是如果我们Marshal.SizeOf(typeof(bool)),获取bool的非托管类型大小得到的就是4个字节。

Sakuya__的博客 2502

MTK Linux DRM分析(八)- KMS drm_crtc.c

CRTC 在 Linux DRM 子系统中是显示控制的核心,负责时序生成、模式设置和管线的调度。理解其工作原理和 API 对于进行底层图形开发、调试显示问题或 simply understanding how your graphics stack works 都至关重要。

iTom1900 1347

Oracle19c SYSAUX表空间爆满?手把手教你清理SM/ADVISOR和AUDSYS占用(附完整SQL)

本文详细解析了Oracle19c中SYSAUX表空间爆满的常见原因及解决方案,重点针对SM/ADVISOR和AUDSYS组件的空间占用问题提供了完整的SQL清理脚本。通过诊断查询、空间清理和预防性维护策略,帮助DBA有效管理SYSAUX表空间,确保数据库稳定运行。

weixin_28338005的博客 235

sizeof(结构体)和内存对齐

有的时候,在脑海中停顿了很久的“显而易见”的东西,其实根本上就是错误的。就拿下面的问题来看:struct T{  char ch;  int   i   ;};使用sizeof(T),将得到什么样的答案呢?要是以前,想都不用想,在32位机中,int是4个字节,char是1个字节,所以T一共是5个字节。实践出真知,在VC6中测试了下,答案确实8个字节。哎,反正受伤的总是我,我已经有点

972

分子对接时,如何批量处理小分子受体和蛋白配体,让他们快速转化为pdbqt格式,然后用vina跑?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1222

C#中sizeof

一. int size = sizeof (int); //4个字节 注意点:sizeof 运算符仅适用于值类型,而不适用于引用类型。sizeof 运算符只能在不安全代码块中使用。如下面的代码将无法编译通过: public struct TestStuct{} int size = sizeof(new TestStuct()); 编译后,提示: 错误 1 “ConsoleApplication3.TestStuct”没有预定义的大小,因此 sizeof 只能在不安全的上下文中使用(请考虑使

2948

015:机载三维激光扫描技术相关知识

机载三维激光扫描系统(LiDAR)是集激光、GPS、INS等尖端技术于一体的三维航空遥感技术,能高效准确获取地表三维信息。该系统由GPS、INS、激光扫描测距系统、成像装置和工作平台组成,各部件协同工作以获取精确的空间定位、运动状态、地表三维坐标及真实色彩信息。通过制定飞行计划、安置GPS基站、激光扫描测量、惯性测量及获取高清数码影像等步骤,机载LiDAR技术能实时获取大范围高精度三维数据。该技术具有扫描速度快、精度高、全数字特征等优势,广泛应用于测绘、工程、环境监测和城市建设等领域,如城市三维模型重建、灾

qq_31762031的博客 1725

西门子博图v16安装密钥提示报错:CryptAcquireContext MS_DEF_PROV Error of containger opening...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值。

**My Coding Family** 3297

SizeOf与Marshal.SizeOf的区别

在程序中,对于值类型,使用SizeOf 对于引用类型,或者含有引用类型的值类型(比如结构体),就需要使用Marshal.SizeOf了。

abc221414的专栏 828

多准则决策方法体系(AHP、熵权法、随机森林、加权线性法、TOPSIS、模糊综合评价)

多准则决策方法体系的基础,是由三大赋权方法和三大评价框架构成的 “3+3” 核心模块。赋权方法聚焦于准则重要性的量化,评价框架则专注于多准则信息的综合集成,二者共同覆盖了从 “确定权重” 到 “输出结果” 的全流程决策需求。

```On Earth, Be Water, By Coding``` 521

C# struct class 在Marshal.SizeOf 的区别

struct 和 class 的区别 最重要的就是 value 和 object 区别了. 但是最近发现另外一个有趣的现象,但是很重要. 一个工程中,因为需要各种结构,于是在开始使用了 struct , 但是觉得有点麻烦,值传递的话,消耗很多,又不喜欢 ref (因为我喜欢写泛型函数) 于是采用了 class , 接下来顺风顺水 , 直到..... [Seriali

norsd的专栏 4919

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

sizeof(C# 参考)

用于获取非托管类型的大小(以字节为单位)。 非托管类型包括下表列出的内置类型以及以下类型: 枚举类型 指针类型 用户定义的结构,不包含任何属于引用类型的字段或属性 下面的示例演示如何检索 int 的大小: C#// Constant value 4: int intSize = sizeof(int); 备注 从 C# 2.0 版开始,将 sizeof 应用于内置类型不再要求使用 uns

不忘初心 方得始终 2039

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

sizeof()与Marshal.SizeOf()的不同

在.NET中一般都是通过sizeof()或Marshal.SizeOf()来获取数据类型的大小,来简要地看一下它们二者有何不同。 sizeof() sizeof()在MSDN中的介绍是,在编译时获得一个数据类型的确定大小,并且被指定为一个常量。如果试图把它用在无效类型上则会出现编译错误,见CS0233。 也就意味着在运行阶段它是没有开销的。 例子 1 sizeof(int) 编...

weixin_30707875的博客 531

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

C#中编程关键知识点笔记

前言:在编程中很多语法、属性和方法认识不清,记得不牢,理解不透,在工作中随手记下。

jinrilife的博客 451
上一篇: 诡异的C++ #define编译错误
下一篇: [预告] 12月9日下午 - MSDN中文网络广播:.NET 4.0 Interop新特性-Type Equivalency
ATField
博客等级 码龄25年 673粉丝 119原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值