C# unsafe code
(*) unsafe 和 fixed
unsafe
{
int[] array = new int[];
for (int i = ; i < array.Length; i++)
{
array[i] = i;
}
fixed (int* p = array)
{
for (int i = ; i < array.Length; i++)
{
System.Console.WriteLine(p[i]);
}
}
}
指针在c#中是不提倡使用的,有关指针的操作被认为是不安全的(unsafe)。因此运行这段代码之前,先要改一个地方,否则编译不过无法运行。
修改方法:在右侧的solution Explorer中找到你的项目,在项目图标(绿色)上点右键,选最后一项properties,然后在Build标签页里把Allow unsafe code勾选上。之后这段代码就可以运行了,你会看到,上面这段代码可以像C语言那样用指针操纵数组。但前提是必须有fixed (int* p = array),它的意思是让p固定指向数组array,不允许改动。因为C#的自动垃圾回收机制会允许已经分配的内存在运行时进行位置调整,如果那样,p可能一开始指的是array,但后来array的位置被调整到别的位置后,p指向的就不是array了。所以要加一个fixed关键字,把它定在那里一动不动,之后的操作才有保障。
另有两点需要注意:
1)指针的使用必须放在unsafe的区域里;unsafe关键字也可作为类或方法的修饰符。
2)fixed (int* p = array)中,p的定义不能写在别处,而且fixed关键字也只能在unsafe区域里使用。
(*) 略简洁的unsafe写法
class Program
{
unsafe public static UInt16 Htons(UInt16 src)
{
UInt16 dest;
// 不能照搬C的源代码,因为有些类型长度不一样,如char(2字节),long(8字节)
// ((char*)&dest)[0] = ((char*)&src)[1];
// ((char*)&dest)[1] = ((char*)&src)[0];
((byte*)&dest)[] = ((byte*)&src)[];
((byte*)&dest)[] = ((byte*)&src)[];
return dest;
}
public static UInt16 ConciseHtons(UInt16 src)
{
UInt16 dest;
unsafe
{
((byte*)&dest)[] = ((byte*)&src)[];
((byte*)&dest)[] = ((byte*)&src)[];
}
return dest;
}
static void Main()
{
UInt16 val = ;
// 如果方法是unsafe的,则必须在unsafe block里调用
unsafe
{
val = Htons(val);
}
Console.WriteLine(val);
// 更简洁的写法是把unsafe block写在函数内部
val = ConciseHtons(val);
Console.WriteLine(val);
}
}
(*) stackalloc
stackalloc的用处仅仅是把数组分配在栈上(默认是分配在托管堆上的)。
class MyClass
{
public int val;
}
class Program
{
static void Main()
{
unsafe
{
MyClass *p = stackalloc MyClass[]; // Error!! 如果类型要放在托管堆上则不行,如果MyClass是struct就OK了
p->val = ;
int *iArray = stackalloc int[]; // OK,在栈上创建数组, int类型本身就是放在栈上的
}
}
}
注意:指针指向的内存一定要固定。凡是C#里的引用类型(一切类型的数组都是引用类型)都是分配在托管堆上的,都不固定。有两种方法强制固定,一种是用stackalloc分配在栈上,另一种是用fixed分配在堆上。
C# unsafe code的更多相关文章
- C#基础—不安全代码(unsafe code)
1.为何要有unsafe 也许是为了实现CLR类型安全的目标吧,默认情况下,C#没有提供指针的使用算法,但是有些情况下也可能需要指针这样直接访问内存的东西(虽然目前我还没有用过),但是有时候程序员非常 ...
- 发布web应用程序是出现unsafe code
找到了解决办法 解决方法参照: https://stackoverflow.com/questions/16567197/publish-web-application-with-unsafe-cod ...
- Unity3D 使用C#指针unsafe
Unsafe code requires the `unsafe' command line option to be specified 在Unity开发中,如果涉及到指针的使用,需要自己定义预处理 ...
- Unity3d中C#使用指针(Unsafe)的办法(转)
近日由于在U3D项目中要使用到数据传递(C++ DLL的数据传递给U3D中的C#),其中涉及到需要使用C#的指针.直接编译会出现以下错误Unsafe code requires the 'unsafe ...
- Java中Unsafe类详解
http://www.cnblogs.com/mickole/articles/3757278.html Java不能直接访问操作系统底层,而是通过本地方法来访问.Unsafe类提供了硬件级别的原子操 ...
- java 非阻塞算法实现基础:unsafe类介绍
一.为什么要有Unsfae.我们为什么要了解这个类 1. java通常的代码无法直接使用操作底层的硬件,为了使java具备该能力,增加了Unsafe类 2.java的并发包中底层大量的使用这个类的功能 ...
- JAVA中神奇的双刃剑--Unsafe
前提 参考资料: Java魔法类:sun.misc.Unsafe 在openjdk8下看Unsafe源码 Unsafe介绍 在Oracle的Jdk8无法获取到sun.misc包的源码,想看此包的源码可 ...
- Understanding sun.misc.Unsafe
转自: https://dzone.com/articles/understanding-sunmiscunsafe The biggest competitor to the Java virtua ...
- Code Project精彩系列(转)
Code Project精彩系列(转) Code Project精彩系列(转) Applications Crafting a C# forms Editor From scratch htt ...
随机推荐
- VS2010下测试程序性能瓶颈
之前看到Qt的有个BUGreport https://bugreports.qt-project.org/browse/QTBUG-13182 这个BUG是在windows下QFileDialog很慢 ...
- /proc/uptime
在Linux中,我们常常会使用到uptime命令去看看系统的运行时间,它与一个文件有关,就是/proc/uptime.这个文件里的两个参数所代表的意义如下. [root@app ~]#cat /pro ...
- chrome无法使用非官方商店扩展解决办法
自己开发的工具性插件不想放在官方商店(当然也有可能是工作相关的工具不能放在官方商店),由于新版本的chrome不允许非官方商店的插件进行安装使用,所以出现一个头疼的问题:每次开启chrome都 ...
- handsontable常规配置的中文API
常规配置: 1.固定行列位置 fixedRowsTop:行数 //固定顶部多少行不能垂直滚动 fixedColumnsLeft:列数 //固定左侧多少列不能水平滚动 2.拖拽行头或列头改变行或列的大小 ...
- androidHandler讲解
秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭". 这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是 ...
- jQuery Pagination Ajax分页插件中文详解(摘)
jQuery Pagination Ajax分页插件中文详解 by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxin ...
- Asp.net开发常用的51个非常实用的代码
1.弹出对话框.点击转向指定页面 Code: Response.Write("<script>window.alert('该会员没有提交申请,请重新提交!')</scrip ...
- 移动开发(webapp)过程中的小细节总结
1.阻止旋转屏幕时自动调整字体大小 html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 { -webkit-text-size-adj ...
- 利用jquery来隐藏input type="file"
<li> <input type="text" name="token" value = "<?php ech$_SESSIO ...
- java——拷贝文件夹方法
public void copyFolder(String oldPath, String newPath) { try { (new File(newPath)).mkdirs(); //如果文件夹 ...