工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VB > 正文
真没想到VB也可以这样用之指针技术
[文章信息]
作者:adambear
时间:2005-02-17
出处:BLOG
责任编辑:方舟
[文章导读]
若想成为VB里的东方不败,熟习VB《葵花宝典》,掌握VB指针技术,乃是不二的法门
advertisement
热点推荐
· 禁止QQ登录的方法
· 给你的XML文件做个数字签名
· ImageReady制作“焰火”小动画
· Java加密和数字签名编程快速入门
· 在VB6中用命令行为模式控制GUI动作
[正文]

上一页  1 2 3 4 5  

  五、VB指针应用

  如前面所说VB里使用指针不象C里那样灵活,用指针处理数据时都需要用CopyMemory将数据在指针和VB能够处理的变量之间来回拷贝,这需要很大的额外开销。因此不是所有C里的指针操作都可以移值到VB里来,我们只应在需要的时候才在VB里使用指针。

  1、动态内存分配:完全不可能、可能但不可行,VB标准

  在C和C++里频繁使用指针的一个重要原因是需要使用动态内存分配,用Malloc或New来从堆栈里动态分配内存,并得到指向这个内存的指针。在VB里我们也可以自己

  用API来实现动态分配内存,并且实现象C里的指针链表。

  但我们不可能象C那样直接用指针来访问这样动态分配的内存,访问时我们必须用CopyMemory将数据拷贝到VB的变量内,大量的使用这种技术必然会降低效率,以至于要象C那样用指针来使用动态内存根本就没有可行性。要象C、PASCAL那样实现动态数据结构,在VB里还是应该老老实实用对象技术来实现。

  本文配套代码中的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类型检查来实现特殊功能的经典应用,出自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

  3、对数组进行批量操作

  用指针进行大批量数组数据的移动,从效率上考虑是很有必要的,看下面的两个程序,它们功能都是将数组的前一半数据移到后一半中:

  【程序九】:

'标准的移动数组的做法
Private Sub ShitArray(ab() As MyType)
 Dim i As Long, n As Long
 n = CLng(UBound(ab) / 2)
 For i = 1 To n
  Value(n + i) = Value(i)
  Value(i).data = 0
 Next
End Sub

  【程序十】:

'用指针的做法
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByVal dest As Long, ByVal source As Long, ByVal bytes As Long)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" _
(ByVal dest As Long, ByVal numbytes As Long)
Private Declare Sub FillMemory Lib "kernel32" Alias "RtlFillMemory" _
(ByVal dest As Long, ByVal Length As Long, ByVal Fill As Byte)

Private Sub ShitArrayByPtr(ab() As MyTpye)
 Dim n As Long
 n = CLng(UBound(ab) / 2)
 Dim nLenth As Long
 nLenth = Len(Value(1))
 'DebugBreak
 CopyMemory ByVal VarPtr(Value(1 + n)), ByVal VarPtr(Value(1)), n * nLenth
 ZeroMemory ByVal VarPtr(Value(1)), n * nLenth
End Sub

  当数组较大,移动操作较多(比如用数组实现HashTable)时程序十比程序九性能上要好得多。

  程序十中又介绍两个在指针操作中会用到的API: ZeroMemory是用来将内存清零;FillMemory用同一个字节来填充内存。当然,这两个API的功能,也完全可以用CopyMemory来完成。象在C里一样,作为一个好习惯,在VB里我们也可以明确的用ZeroMemory来对数组进行初始化,用FillMemory在不立即使用的内存中填入怪值,这有利于调试。

  4、最后的一点

  当然,VB指针的应用决不止这些,还有什么应用就要靠自己去摸索了。对于对象指针和字符串指针的应用我会另写文章来谈,做为本文的结束和下一篇文章《VB字符串全攻略》的开始,我在这里给出交换两个字符串的最快的方法:

  【程序十一】

'交换两个字符串最快的方法
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, ByVal Length As Long)

Sub SwapStrPtr3(sA As String, sB As String)
 Dim lTmp As Long
 Dim pTmp As Long, psA As Long, psB As Long
 pTmp = StrPtr(sA): psA = VarPtr(sA): psB = VarPtr(sB)
 CopyMemory ByVal psA, ByVal psB, 4
 CopyMemory ByVal psB, pTmp, 4
End Sub

  对不起,为了一点点效率,又用了Any!关于StrPtr,下一篇文章我会来谈。

  自己来试试吧!欲练神功,赶快行动!

上一页  1 2 3 4 5  

天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • 在VB6中用命令行为模式控制GUI动作
  • VB设计Win2000下截获IP数据包程序
  • 真没想到VB也可以这样用之VB能做什么
  • 用VB编写异步多线程下载程序
  • 适合Visual Basic初学者的10个小技巧
  • 民营家电商排队造手机 设备商全面杀入
  • 英特尔澄清杨旭任职传闻 官方没宣布此消息
  • 国资委河北密制联通拆分方案
  • 垃圾邮件害人害企害国 清除垃圾邮件不手软
  • 中兴携手阿尔卡特 全球逐鹿CDMA
  • 用友总裁王文京:誓将ERP变成“大众消费”
  • 香港消费者委员会:数码相机最贵未必最好
  • 外电称中兴正评估西门子手机业务 或能并购
  • Advertisement