VB.NET 指针

在.NET中,对指针指向数据的存储函数都封装在marshal类中,主要的函数包括:Copy、PtrToStringUni 、PtrToStructure 、OffsetOf、WriteXXX,RreadXXX等。

 '使用<StructLayout(LayoutKind.Sequential)>属性告诉net编译器:结构的元素在内存中按其出现的顺序排列 
 <StructLayout(LayoutKind.Sequential)> _ 
 Public Structure DEFUDT_Test 
 Public bytb As Byte 
 Public i32a As Int32 
 End Structure 
 
 Public Function fnGetIntptr1() As IntPtr 
 '取得一个4字节数组指针 
 Dim tabytTest(3) As Byte 
 '以下语句告诉net垃圾回收进程不对tabytTest进行处理,也就是说tabytTest占用的内存区域固定不变。 
 Dim thObject As GCHandleGCHandle = GCHandle.Alloc(tabytTest, GCHandleType.Pinned) 
 Dim tpObject As IntPtr = thObject.AddrOfPinnedObject() '取得指向字节数组的指针 
 
 '取得一个指向32位内存数据的指针, 
 '由于使用gchandle取指针的方法只能对引用的对象有效, 
 '所以对如int32等值类型必须使用将其封装成为一个对象的方法以变为引用类型 
 Dim ti32Test As Object = Convert.ToInt32(0) 
 '以下语句告诉net垃圾回收进程不对ti32test进行处理,也就是说ti32Test的内存位置固定不变。 
 Dim thObject1 As GCHandleGCHandle = GCHandle.Alloc(ti32Test, GCHandleType.Pinned) 
 Dim tpObject1 As IntPtr = thObject1.AddrOfPinnedObject() '取得ti32Test的首地址 
 
 Dim tudtTest1 As DEFUDT_Test 
 '由于结构是一种值类型变量,为保证指针申请方便,我们申请 
 '取得一个和结构tudtTest1大小一致的字节数组指针,只要空间占用长度和结构一样就可以了 
 '由于net在结构封装中会插入额外的数据位,所以一定要用sizeof方法得到结构在非托管使用时的实际大小 
 Dim tudtTest(Marshal.SizeOf(tudtTest1)) As Byte 
 Dim thObject2 As GCHandleGCHandle = GCHandle.Alloc(tudtTest, GCHandleType.Pinned) 
 Dim tpObject2 As IntPtr = thObject2.AddrOfPinnedObject() '取得指向结构的指针 
 
 '在这儿你可以写对指针处理的任意代码(在例2中会给予补充)…… 
 
 '在使用完毕后一定要释放指针指向的内存块,让垃圾回收器可对这个内存块回收处理 
 If thObject.IsAllocated Then 
 thObject.Free() 
 End If 
 If thObject1.IsAllocated Then 
 thObject1.Free() 
 End If 
 If thObject2.IsAllocated Then 
 thObject2.Free() 
 End If 
 End Function

上例中VB.NET指针流程处理可以归纳为:
1、定义一个具有合适内存长度的引用变量(关于引用变量和值变量的差异可以参观VB.NET的书籍)
2、使用GCHandle.Alloc方法将变量的内存区域固定下来。
3、使用GCHandle对象的AddrOfPinnedObject取得该内存区域的首地址并赋值给指针变量.
4、对指针进行操作
5、使用GCHandle对象的free方法释放指针指向的内存区域以便NET垃圾回收器可以回收这个内存空间
6、VB.NET指针所指向数据的存取

在.NET中,对指针指向数据的存储函数都封装在marshal类中,主要的函数包括:Copy、PtrToStringUni 、PtrToStructure 、OffsetOf、WriteXXX,RreadXXX等,其中WriteXXX的表示向指针所表示的地址中写入XXX类型的数据,而ReadXXX中作用就是将VB.NET指针所在地址的数据以XXX类型方式读出。

 

转载于:https://www.cnblogs.com/lbnnbs/p/4782071.html

此代码是《VB真是想不到系列之三:VB指针葵花宝典之函数指针》的配套代码。 本系列文章可见: http://www.csdn.net/develop/list_article.asp?author=AdamBear 本代码主要是用来谈函数指针VB内部的应用之一,给出了qsort和ShellSort的实现。其中ShellSort完全是取自1998年5月VBPJ的Black Belt专栏里的源代码,可以说本文的思想基本上也来自这篇专栏文章。 ShellSort提共了三种不同的实现方法,分别是如下: PolySort1: 用Variant和对象缺省属性来比较。 PolySort2:用ISortable接口的多态对象技术来实现 PolySort3:用函数指针强制回调技术来实现。 分别运行一下这三个程序,可以发现用函数指针是最快的。值得一提作者的钻研精神,完全在VB里实现同一种算法完全三种不同的实现,而且一个比一个好,我非常佩服。 我原以为qsort应该会比它快不少,从算法上来说是这样,不过做出来才发现,要在VB里做出比它快的qsort很难,即使经过了仔细的优化。这是因为qsort的实现上比shellsort复杂,在C里多几次比较、多几次无用的移动影响不大,但在VB里多用一次API回调的Compare、多用一次CopyMemory都是很大的开销。而且qsort要嵌套调用(不嵌套在VB里也慢),我们还要尽量节约堆栈,虽然1M的默认堆栈大小可以被扩充(有相邻的空闲空间时),但是我们依然要考虑可能存在的溢出,所以我做的qsort仅两个参数,两个局部Long型变量。大家可以参考一下我最终的qsort的源代码。 见QSort工程里的basQSort模块,有详细注释。 虽然qsort还是比shellsort慢得多,但是可以说qsort已经进行了较好的优化。可见在VB里一个算法好不好,不能仅仅从理论上看,一个差一点但实现简单的算法和一个好一点但实现上复杂的算法在VB里谁好谁坏很难说。所以从实践意义上,ShellSort的确是个不错的算法。 无论ShellSort还是qsort,它们都还可以更加快,我在文章里说过,那必须要Hack一下SafeArray。 本系列第四篇文章《VB真是想不到系列之三:VB指针葵花宝典之数组指针》里再谈,这篇文章很快就会出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值