闁衡偓閹増顥� (0) +1 閻犙嶆嫹 (0) +1 闂婎亷鎷� (0) +1
闁衡偓閹増顥戦柟瀛樺姇婵拷闁哄被鍎冲﹢鍛村绩閹増顥�>>

正在阅读:巧用Win32 API函数增强VB位操作功能巧用Win32 API函数增强VB位操作功能

2005-09-15 10:14 出处: 作者:刘琦 责任编辑:moningfeng

方法2:利用安全数组借用内存的方法实现

  方法1虽然用起来简单方便,但是要执行API函数调用,函数调用时要保存现场、恢复现场,时间开销很大,效率太低,因此不适合大数据量密集运算的场合。笔者在开发加密软件时曾使用方法1来处理文件数据,效果很不理想,速度奇慢。其实有一种方法可以巧妙的骗过VB,让一个数组直接访问其他变量的内存空间,从而达到拆分、合并整形变量的目的。由于这种方法省去了API函数调用,因此效率非常高。下面就让我们认识一下VB中的安全数组。VB中的安全数组与C语言中的数组有很大的差别,虽然在VB和C语言中数组变量都是指针,但C语言中的数组变量直接指向数组元素,而 VB中的数组变量却是指向一个SafeArray结构,这个SafeArray结构中的pvData域才指向数组元素。

  那么这个SafeArray结构是做什么用的呢?它存储着数组的上界、下界、维数、元素大小等一系列的信息,正是SafeArray结构的存在,使得VB程序能够对数组的访问做越界检查,这就是为什么VB中的数组叫做安全数组的原因,而C语言中的数组显然不具备越界检查的能力。当然安全数组的缺点就是没有C语言的数组灵活,但尽管如此,我们还是有办法操纵它,通过对安全数组的操纵,可以让它访问任意的内存位置,甚至包括其他变量的内存空间。对于一维数组来说,它的SafeArray结构如下:

Type SafeArray1d '1维数组的 SafeArray 定义

cDims As Integer '维数

fFeatures As Integer '标志

cbElements As Long '单个元素的字节数

clocks As Long '锁定计数

pvData As Long '指向数组元素的指针

cElements As Long '维定义,该维的元素个数

Lbound As Long '该维的下界

End Type


  如果显式的给一个数组变量赋值,让它指向我们自己创建的SafeArray结构,就可以通过设置SafeArray结构的pvData域来访问任意内存位置。请看示例代码:

Public Declare Function VarPtrArray Lib "msvbvm60.dll" _Alias "VarPtr" (ptr() As Any) As Long

Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Sub Command2_Click()

Dim pBytesInLong() As Byte

Dim SA1D As SafeArray1d

Dim i As Long

With SA1D

.cDims = 1

.fFeatures = 17

.cbElements = 1

.clocks = 0

.pvData = VarPtr(i) '使数组的数据指针指向长整形变量 i

.cElements = 4

.Lbound = 0

End With


'使数组变量(其实就是个指针)指向我们自己创建的 SafeArray1d 结构

CopyMemory ByVal VarPtrArray(pBytesInLong), VarPtr(SA1D), 4

i = &HFFFFFFFF

MsgBox pBytesInLong(1) '访问长整形变量的第2个字节(从低处开始数)

pBytesInLong(3) = 0 '把全部数组元素设为0

pBytesInLong(2) = 0

pBytesInLong(1) = 0

pBytesInLong(0) = 0

MsgBox i '你会发现 i 也变成了 0

'把数组变量(其实就是个指针)指向 0,既 C 语言中的 NULL

CopyMemory ByVal VarPtrArray(pBytesInLong), 0&, 4

End Sub


  从代码中可以看到我们用一个字节数组借用了长整形变量i的地址空间,从而可以通过数组元素访问变量i的各个字节。这样也实现了拆分、组合整形变量的目的,和方法1殊途同归,但很显然方法2不需要函数调用,不需要数据复制,因此效率非常高。用这种方法,我专门构筑了一个模块:FastBitEx模块,实现了方法1中提及的6个函数的Fast版本,代码很长,不在这里给出,请读者参阅代码。
键盘也能翻页,试试“← →”键

相关文章

关注我们

最新资讯离线随时看 聊天吐槽赢奖品
闁归潧顑嗗┃鈧悹浣告健濡拷闁搞儳鍋涢崺灞俱亜閸洖鍔�