top
Loading...
VB“變態”用法之有用技術和沒用指針
Bill McCarthy在那篇《Modify a Varialbe's Pointer》里用SafeArray實現多進程的數組共享內存,他考慮了數組變量的類型,因此可以兼容大部分數值類型的數組,是一個非常不錯的東西。我這里不講它實現的具體方法,只是想和大家一起看看SafeArray還能做什么。

修改SafeArray結構的pvData指針卻是一個非常有用的技術,通過修改pvData,就能夠通過數組直接訪問指定的內存。

和上一篇文章包裝字串指針類一樣,通過修改pvData,我們也可以包裝一些普通數值類型變量的指針類。

我在指針的第一篇文章里說過,要想實現C語言里'*'這個取指針所指變量值功能,必須要用CopyMemory。實際上,我說錯了,我們完全可以實現和C里一樣的指針,如下:

//C語言
Long L;
Long* pL = &L;
*pL = 12;
printf("L = %d *pL = %d", l, *pl);
'VB里
Dim pL As New pLong, L As Long
pL.Attach L
'也可以 pL.Ptr = VarPtr(L)
pL = 12
Debug.Print "L ="; L; " *pL ="; pL

結果都能夠通過修改pL指針,達到修改變量L的目的。

上面VB代碼里的pLong就是一個包裝好的Long型變量的指針類,下面看看如何來實現它:

Option Explicit
'********************************************************
'pLong.cls
'包裝一個Long型指針的類
'作者: 熊超 ID: AdamBear 2002年3月18日
'http://www.csdn.net/Author/AdamBear
' 你可以自由使用本類模塊,不過請保留本聲明
'********************************************************

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

Private m_Arr(0) As Long


'缺省屬性
Public Property Get Data() As Long
Data = m_Arr(0)
End Property

Public Property Let Data(ByVal Value As Long)
m_Arr(0) = Value
End Property

Public Sub Attach(Target As Long)
Ptr = VarPtr(Target)
End Sub

Public Property Let Ptr(ByVal Target As Long)
Dim pSA As Long

'得到SafeArray結構指針pSA
CopyMemory pSA, ByVal VarPtrArray(m_Arr), 4
'這個指針偏移12個字節后就是pvData指針
CopyMemory ByVal (pSA + 12), Target, 4

End Property

Public Property Get Ptr() As Long
Ptr = m_SA.pvData
End Property


Private Sub Class_Terminate()
CopyMemory ByVal VarPtrArray(m_Arr), 0&, 4
End Sub

要將它改成Byte的指針類,只需要將上面的代碼中m_Arr數組的類型,Data屬性和Attach方法中的參數類型改為Byte型即可。

當我們這樣做出pLong、pByte、pInteger后,我們就能夠玩點和C里一樣的花樣了。

Sub Main()
Dim pB As New pByte, B As Byte
Dim pI As New pInteger, I As Integer
Dim pL As New pLong, L As Long

'用Attach方法將經過類型檢查,直接用Ptr屬性則可以繞過類型檢查
pB.Attach B
pI.Attach I
pL.Attach L

'試試指針
B = 1
Debug.Print "B ="; B; " *pB ="; pB

pB = 1
Debug.Print "B ="; B; " *pB ="; pB

I = 1000
Debug.Print "I ="; I; " *pI ="; pI

pI = 2000
Debug.Print "I ="; I; " *pI ="; pI

L = 40000
Debug.Print "L ="; L; " *pL ="; pL

pL = 60000
Debug.Print "L ="; L; " *pL ="; pL

'試試C里的類型轉換
'用Integer指針訪問Long型變量
pI.Ptr = VarPtr(L)
Debug.Print "*pI ="; pI

End Sub

搞出這幾種普通數值類型的指針類有什么用?基本上沒有什么大用。不過是證明一種方法的可行性,和演示技術。這種技術還有什么用,需要的時候還會再談。
作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗