现在的位置: 首页 > 综合 > 正文

UnSafe & Fixed

2013年10月24日 ⁄ 综合 ⁄ 共 1854字 ⁄ 字号 评论关闭

      c#在默认情况下生成的都是安全代码,即进行了代码托管(.NET的CLR机制好处之一是 ,进行代码托管,适时的释放内存,程序员便不必考虑资源的回收问题),而此时,指针不能出现在安全代码的编译条件下。

 一、unsafe  

     如果因需要想在c#中使用指针,那么unsafe便是一个通道(当然在使用前,需在项目属性的生成选项中,选择“允许不安全代码”)。

example 1:

a) 创建项目,项目属性->生成->选择“允许不安全代码”

b) 编写代码

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. namespace ConsoleDll
  6. {
  7.     //此处为c++动态库的调用,因DllC++.dll是示例测试文件,为不影响代码演示,此处屏蔽
  8.     //public class Code
  9.     //{
  10.     //    [DllImport("DllC++.dll")]
  11.     //    public unsafe static extern int Add(int a, int* b);
  12.     //}
  13.     class Program
  14.     {
  15.         public unsafe static int Add(int a, int* b)//此处使用指针,需要加入非安全代码关键字unsafe
  16.         {
  17.             return a + *b;
  18.         }
  19.         static void Main(string[] args)
  20.         {
  21.         unsafe//此代码块为非安全代码,可以使用指针
  22.         {
  23.             int resDll,resInner, a;
  24.             int* b;//如果在安全代码条件下,编译不会通过对指针的定义
  25.             a = 1;
  26.             b = &a;
  27.            // resDll = Code.Add(a, b);
  28.             resInner = Add(a,b);
  29.         }
  30.         }
  31.     }
  32. }

 

     上面代码简单的示范了何种情况下可以使用指针。

 

二、fixed

      fixed其实是在非安全代码下用到才会有意义的。因为他负责对指针所指向的“动态分配内存的对象或对象中的成员”简称“对象”进行锁定(之所以要锁定,是因为即使在非安全代码模式下,这些对象一样的使用CLR的代码托管,这样的话,很可能造成对象的地址变动,就是因为CLR对资源重新分配的不确定性,假使指针在未完成对对象的操作时,对象地址变动,那么指针指向的地址就会出现混乱,很可能造成内存泄漏甚至系统崩溃。如果使用fixed进行锁定,那么只有在执行完fixed模块后,指针所指向的对象才能被移动)。

example 2:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. namespace ConsoleDll
  6. {
  7.         public static int Add(int[] a,int b)
  8.         {
  9.             unsafe
  10.             {
  11.                 fixed (int* pa = a)//此处将锁住a,使得在fixed操作块内,a不会被CLR移动
  12.                 {
  13.                     return *pa + b;
  14.                 }
  15.             }
  16.             
  17.         }
  18.         static void Main(string[] args)
  19.         {
  20.             int[] a = new int[1];
  21.             a[0] = 1;
  22.             int b = 2;
  23.             int res = Add(a,b);
  24.         }
  25.     }
  26. }

       上述代码需注意的是:pa的地址也是被固定了的,所以不能对他进行赋值操作。

抱歉!评论已关闭.