如果想发较大的信件,请用Ninputer @ gmail.com
不要在我的Blog评论中张贴广告,除非同意向我付款。
上次我们已经见识了inlineIL的强大功能,现在我们继续挖掘它的应用。大家都知道VB.NET禁止使用不安全代码,这对于VB的定位来说没什么。可是总有一些从VB6过来的人,他们对VarPtr这种超级不安全的指针念念不忘,而这也确实是突破旧VB语言限制,转变为VB黑客级人物的利器。为了让这些人在VB.NET上继续他们的黑客事业,我们也只有再次动用嵌入IL这一“斧头”。
绝大部分VB6使用指针的功能,都能利用System.Runtime.InteropServices.Marshal类来完成,比如Copy内存,在堆里分配内存或者读写指针等等。现在我们缺少的只是获取变量的指针。现在有一个类Class2,有一个字段i,现在假设我们要获取i的地址,并做一些和非托管程序的互操作。变量i是Class的字段,分配在托管堆中,它的地址是可以被CLR挪动的。我们要获取他的指针,必须将它定在内存中。好在.NET提供了这类方法,虽然不及C++/CLI的pin_ptr那样强大好用……现在嵌入IL
Class Class2Class Class2 Public Shared Sub Main()Sub Main() Dim o As New Class2 o.Test() End Sub Private i As Integer = 1 Public Sub Test()Sub Test() Dim addr As IntPtr #If IL Then .locals(int32& pinned p) ldarg.0 ldflda int32 Class2::i stloc p ldloc p conv.i call native int native int::op_Explicit(void*) stloc addr #End If Marshal.WriteInt32(addr, 100) Console.WriteLine(i.ToString()) End Sub End Class
注意代码中的pinned,他定义的指针指向一个变量后,就会将变量的地址定在托管堆中,直到这个指针的生命周期结束。在C#中,我们是用fixed来做这件事的。如果是获取局部变量的地址,那么无需使用pinned,因为栈中的值类型变量是不会被移动的。接下来我们将指针转换为无类型信息的IntPtr。因为嵌入IL功能的限制,我们无法在VB代码部分使用嵌入IL声明的变量,所以只有用一个IntPtr作桥。好了,看看结果吧,还不算太难哈。
打印 | posted on Tuesday, March 15, 2005 10:01 AM | Filed Under [ 技术随笔 ] | 收藏本页 (百度搜藏)(QQ书签)(Live收藏)(Google书签)(Yahoo书签)(新浪ViVi)(搜狐网摘)(365Key网摘)(天极网摘)(博采网摘)(和讯网摘)
Powered by:
Copyright © Ninputer