在C#的安全环境下使用指针操作

自动换行  【由 孤帆代码着色器1.0.1  着色】  孤帆Blog

 
 
1       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    
19        
20        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    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值