Marshal.SizeOf和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<T>
2: {
3: T a;
4: }
如果对Marshal.SizeOf传入MyStruct<>或者MyStruct<int>这样的类型,则抛出ArgumentException,因为Marshal.SizeOf完全不支持泛型。这个是历史遗留问题,从本质上来讲实例化的模板类型(MyStruct<int>)应该是支持的,据说当时主要是没有时间加上对模板的支持。
同样的,sizeof也不支持模板类型,而且连MyStruct<int>这样子的类型也不支持。C#编译器会对sizeof(MyStruct<int>)报错:error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('SizeOf.Program.MyStruct<int>')
Marshal.SizeOf和sizeof的区别的更多相关文章
- sizeof和strlen的区别
一.sizeof sizeof(...)是运算符,而不是一个函数. sizeof操作符的结果类型是size_t,在头文件中typedef为unsigned int,其值在编译时即计算好了, ...
- Sizeof与Strlen的区别与联系
转自:http://www.cnblogs.com/carekee/articles/1630789.html 一.sizeof sizeof(...)是运算符,在头文件中typedef为uns ...
- Sizeof与Strlen的区别与联系(转)
Sizeof与Strlen的区别与联系 一.sizeof sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组.指针.类型 ...
- C++-sizeof和strlen的区别
一.sizeof sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组.指针.类型.对象.函数等. 它的功能是:获得保 ...
- sizeof和strlen的区别和联系总结
link:http://blog.csdn.net/ghevinn/article/details/9974967 strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头 ...
- 【转】Sizeof与Strlen的区别与联系
原文地址:http://www.cnblogs.com/carekee/articles/1630789.html 1.sizeof sizeof(...)是运算符,在头文件中typedef为uns ...
- C++Sizeof与Strlen的区别与联系
一.sizeof sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组.指针.类型.对象.函数等. 它的功能是:获得保 ...
- Sizeof与Strlen的区别【转】
本文转载自:http://www.cnblogs.com/carekee/articles/1630789.html Sizeof与Strlen的区别与联系 一.sizeof sizeof(.. ...
- 我也介绍下sizeof与strlen的区别
本节我也介绍下sizeof与strlen的区别,很简单,就几条: 1. sizeof是C++中的一个关键字,而strlen是C语言中的一个函数:2. sizeof求的是系统分配的内存总量,而strle ...
- C++基础--sizeof和strlen的区别
首先,来运行一段程序: #include "stdafx.h" #include <stdio.h> #include <string.h> int mai ...
随机推荐
- IPC对象的持续性
转载:http://book.51cto.com/art/201006/207275.htm <UNIX网络编程:第2版.第2卷,进程间通信>本书全面深入地讲解了各种进程间通信形式,包括消 ...
- Oracle学习笔记:parallel并行处理
在使用oracel查询时,可以通过并行提高查询速度.例如: ) from table_name a; 强行启用并行度来执行当前SQL.加上这个说明之后,可以强行启用Oracle的多线程处理功能,提高效 ...
- Spark(十二)SparkSQL简单使用
一.SparkSQL的进化之路 1.0以前: Shark 1.1.x开始:SparkSQL(只是测试性的) SQL 1.3.x: SparkSQL(正式版本)+Datafram ...
- Web前端开发最佳实践(10):JavaScript代码不好读,不好维护?你需要改变写代码的习惯
前言 这篇文章本应该在上一篇文章:使用更严格的JavaScript编码方式,提高代码质量之前发布,但当时觉得这篇文章太过基础,也就作罢.后来咨询了一些初级的开发者,他们觉得有必要把这篇文章也放上来.尽 ...
- 华三IRF的配置
https://blog.csdn.net/VictoryKingLIU/article/details/79255901 拓扑结构 1 配置成员编号(重启) 2 配置成员优先级(大的主设备) 3 配 ...
- win7 fiddler报“Creation of the root certificate was not successful”的问题
cd "C:\Program Files (x86)\Fiddler2" makecert.exe -r -ss my -n "CN=DO_NOT_TRUST_Fiddl ...
- CentOS7的一些指令
hostnamectl --static set-hostname yuanxu#永久修改主机名 systemctl stop firewalld.service #停止firewall system ...
- PHP 数组的添加和读取
在实际的开发中,会经常使用数组的添加和读取.这里把经常使用的操作记下来,以备以后查阅. <?php //一维数值数组 $list = array('wang','god'); $list[] = ...
- 使用apache的ab命令进行压测
1. 背景:互联网发达的今天,大大小小的网站如雨后春笋,不断出现,但是想要做出一个网站很简单,但是想要做好一个网站,非常非常难,首先:网站做好之后的功能怎么样这都是次要的,主要的是你的网站能承受怎么样 ...
- C++ 基础 杂类
1.set: 基本上跟map是相同(只有一个键),set是key-value 放在一起,map 是分开的,既然都加key ,所以set<> 的内容不可能有重复的情况出现 example: ...