经过长时间学习VB.NET,于是和大家分享一下VB.NET指针应用,看完本文你肯定有不少收获,希望本文能教会你更多东西。VB里使用指针不象C里那样灵活,用指针处理数据时都需要用CopyMemory将数据在指针和VB能够处理的变量之间来回拷贝,这需要很大的额外开销。因此不是所有C里的指针操作都可以移值到VB里来,我们只应在需要的时候才在VB里使用指针。
1、VB.NET指针应用动态内存分配:完全不可能、可能但不可行,VB标准
在C和C++里频繁使用指针的一个重要原因是需要使用动态内存分配,用Malloc或New来从堆栈里动态分配内存,并得到指向这个内存的指针。在VB里我们也可以自己用API来实现动态分配内存,并且实现象C里的指针链表。
但我们不可能象C那样直接用指针来访问这样动态分配的内存,访问时我们必须用CopyMemory将数据拷贝到VB的变量内,大量的使用这种技术必然会降低效率,以至于要象C那样用指针来使用动态内存根本就没有可行性。要象C、PASCAL那样实现动态数据结构,在VB里还是应该老老实实用对象技术来实现。
#T#本文配套代码中的LinkedList里有完全用指针实现的链表,它是使用HeapAlloc从堆栈中动态分配内存,另有一个调用FindFirstUrlCacheEntry这个API来操作IE的Cache的小程序IECache,它使用了VirtualAlloc来动态分配内存。但实际上这都不是必须的,VB已经为我们提供了标准的动态内存分配的方法,那就是:对象、字符串和字节数组限于篇幅,关于对象的技术这里不讲,LinkedList的源代码里有用对象实现的链表,你可以参考。字符串可以用Space$函数来动态分配,VB的文档里就有详细的说明。关于字节数组,这里要讲讲,它非常有用。我们可用Redim来动态改变它的大小,并将指向它***个元素的指针传给需要指针的API,如下:
- dim ab() As Byte , ret As long
- '传递Null值API会返回它所需要的缓冲区的长度。
- ret = SomeApiNeedsBuffer(vbNullString)
- '动态分配足够大小的内存缓冲区
- ReDim ab(ret) As Byte
- '再次把指针传给API,此时传字节数组***个元素的指针。
- SomeApiNeedsBuffer(ByVal VarPtr(ab(1)))
在本文配套程序中的IECache中,我也提供了用字节数组来实现动态分配缓冲区的版本,比用VirtualAlloc来实现更安全更简单。
2、VB.NET指针应用突破限制
下面是一个突破VB类型检查来实现特殊功能的经典应用,出自Bruce Mckinney的《HardCore Visual Basic》一书。
将一个Long长整数的低16位作为Interger型提取出来,
- '标准的方法,也是高效的方法,但不容易理解。
- Function LoWord(ByVal dw As Long) As Integer
- If dw And &H8000& Then
- LoWord = dw Or &HFFFF0000
- Else
- LoWord = dw And &HFFFF&
- End If
- End Function
- '用指针来做效率虽不高,但思想清楚。
- Function LoWord(ByVal dw As Long) As Integer
- CopyMemory ByVal VarPtr(LoWord), ByVal VarPtr(dw), 2
- End Function