自动换行 【由 孤帆代码着色器1.0.1 着色】 孤帆Blog1 C#中要操作指针正规的方法是把代码块标为"unsafe"。虽然不安全代码 2 可以触及些许C代码的感觉,但不安全代码还是存在很多的限制,并且代码的 3 运行也受到限制. 4 那么有没有其他替代方法呢?没有.当然只依靠C#按常规的方法是很难 5 达到我们的远大理想的!既然如此我们能否用其他语言来辅助实现呢?可 6 以!废话!不然我写这些垃圾做什么?现在请听我慢慢道来.各位看官请喝 7 茶! 8 9 一、.Net里的内部指针截获 10 在托管环境下用户涉及到的指针操作都是由CLR来完成的(不安全代码除外 11 ).但这样并不表示我们在安全的.Net下没有使用指针,因为所有涉及到字段的 12 移动、更新必须通过指针操作才能实现的. 13 那么CLR又怎样知道我们什么时候要更新字段数据、什么时候只需要获取字 14 段数据呢?(呵呵!喝茶先) 15 1. C#程序中的"指针"表示方式 16 out、ref关键字就是我们的寻找的答案了。慢!先让我简单解释一下这 17 些家伙是什么东西先(郁闷!又要背书了!背的不好各位大哥请自行找书了). 18 1920 ref :引用实参(实参必须已经初始化) 21 out :跟ref差别是不检查实参是否已经初始化 22 OK!现在各位大概已经知道我们的目标在那里了吧!没错!我们需要的就是ref 23 和out我们的实参.为什么?别理她什么东东,暂且把她们当作我们的白雪公主(指针 24 )来看待. 25 26 2.怎样从out或ref中得到实参指针呢? 27 如前面所说我们的指针操作都是如CLR来帮助完成的,所以当用out或ref我们 28 的实参时实际上CLR就是封送托管中字段的指针. 29 所以我们只要把CLR传过来的指针截获就ok了!怎样截获呢?用其他允许指针 30 操作的语言做个dll来实现. 31 以下我给出用asm写的dll源代码: 32 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 33 ;getVarPtr.asm 34 .386 35 .Model Flat,StdCall 36 Option CaseMap:None 37 38 .code 39 DllMain proc hInstance:DWORD,reason:DWORD,unused:DWORD 40 mov eax,1 41 ret 42 DllMain endp 43 44 ;*************************************************** 45 ;功能 :获取CLR传过来的指针函数. 46 ;返回值:CLR传过来的指针 47 ;用C/C++描述如下 48 ;int getVarPtr(int var) 49 ;{ 50 ; return var; 51 ;} 52 ;*************************************************** 53 getVarPtr proc 54 mov eax,[esp+4] 55 ret 4 56 getVarPtr endp 57 58 end DllMain 59 ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 60 61 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 62 导出函数文件 getVarPtr.def 63 EXPORTS 64 getVarPtr 65 ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 66 67 68 二、动刀杀牛! 69 说了那么多废话还是给个代码让大家看下,辛苦各位了! 70 71 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 72 class CPtrINSafeEnv 73 { 74 //我们的获取CRT传过来的指针函数 75 [DllImport("getVarPtr.dll")] 76 public static extern int getVarPtr(ref int var) ; 77 78 //内存拷贝的好东西 79 [DllImport("kernel32", EntryPoint="RtlMoveMemory")] 80 public static extern void CopylpInt2Int(ref int dest,int src,int nLen); 81 [STAThread] 82 static void Main(string[] args) 83 { 84 int dwTest=123456; 85 int pdwTest=0; 86 int dwTmp=0; 87 Console.WriteLine("dwTest={0},pdwTest={1},dwTmp={2}/n", 88 dwTest.ToString() ,pdwTest.ToString(),dwTmp.ToString()); 89 90 //动态获取dwTest在托管环境下的地址 91 pdwTest=getVarPtr(ref dwTest); 92 Console.WriteLine ("dwTest在托管环境下的实际地址是:" 93 + pdwTest.ToString()); 94 95 //通过dwTest的指针把dwTest的数据复制到dwTmp 96 CopylpInt2Int(ref dwTmp,pdwTest,4); 97 Console.WriteLine("/n通过dwTest的指针把dwTest的数据复制到dwTmp后/ndwTmp=" 98 + dwTmp.ToString()); 99 100 Console.Read(); 101 } 102 } 103 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 104 105 简单解释 106 107 上面的代码执行过程如下: 108 1.获取dwTest的托管指针保存到pdwTest中 109 2.通过保存在pdwTest中dwTest的指针,把dwTest的数据拷贝到dwTmp中去. 110 111 提示:运行时请把dll拷贝到程序运行目录 112 113 下载地址:http://upload.programfan.com/upfile/200508051233342.rar 115 三、这种方法是否安全 116 117 1.以上的方法是否安全? 118 不安全!因为"指针操作都是不安全的!!"^_^.所以安全是相对的 119 .谁敢确保CLR处理我们的指针就安全呢?Java不也内存泄漏吗?我们都 120 是见效率忘安全中人!呵呵!! 121 122 2.如果GC压缩内存我们的代码是否会出错呢? 123 不会.只要我们是动态的获取字段指针就不会出现错误! 124 125 四、有什么用呢? 126 呵呵!当然是为了不安分的自己,满足一些无法用常规实现的不可告人的 127 目的(最直接的就是速度了,还有就是....自己想). 128
在C#的安全环境下使用指针操作
最新推荐文章于 2024-11-09 13:58:10 发布