如何在Visual Basic 中取得变量的内存地址(Address of Variables)
本文适用于
Microsoft Visual Basic Learning Edition for Windows, versions 5.0, 6.0
Microsoft Visual Basic Professional Edition for Windows, versions 5.0, 6.0
Microsoft Visual Basic Enterprise Edition for Windows, versions 5.0, 6.0
摘要
很少有vb程序员需要获得一个变量的低级信息,例如内存地址。然而,一些API函数需要这种
信息,本文描述的方法可以帮助VB程序员取得这些信息
VarPtr - Returns the address of a variable.返回变量的地址
VarPtrArray - Returns the address of an array.返回数组地址
StrPtr - Returns the address of the UNICODE string buffer.返回UNICODE字符串缓冲区地址
VarPtrStringArray - Returns the address of an array of strings.
返回字符串数组地址
ObjPtr - Returns the pointer to the interface referenced by an object variable. 返回一个对象的接口引用指针
正文
VarPtr
这个函数用来取得一个变量或一个数组的地址,传递一个变量名或者数组然后返回地址。但是,你要明白动态数组可能会被vb重新分配内存,因此你必须小心当你用VarPtr取得数组的地址的时候。
Dim lngVariableAddress as Long
Dim dblMyVariable as Double
lngVariableAddress = VarPtr(dblMyVariable)
Dim lngElementAddress as Long
Dim lngArrayOfLongs(9) as Long
' following will get address of 4th element
lngElementAddress = VarPtr(lngArrayOfLongs(3))
局限:这个函数不能用于取得数组的地址
VarPtrArray当数组在Visual Basic中存为SAFEARRAYs结构时,要取得SAFEARRAYs结构的地址,你要使用VarPtrArray 函数,下面分别是vb5、vb6的定义:
Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" _
(Var() as Any) As Long
Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" _
(Var() as Any) As Long
Dim lngSafeArrayAddress as Long
Dim lngArrayOfLongs(9) as Long
lngSafeArrayAddress = VarPtrArray(lngArrayOfLongs())
局限:VarPtrArray函数不能用于取得一个字符串数组的地址,因为vb会对字符串进行UNICODE/ANSI转换,如果对字符串数组使用VarPtrArray,将会得到一个临时ANSI数组拷贝的地址。
StrPtr
取得字符串第一个字符的地址
Dim lngCharAddress as Long
Dim strMyVariable as String
strMyVariable = "Some String"
lngCharAddress = StrPtr(strMyVariable)
当你在API调用中需要传递一个UNICODE字符串指针时可以使用这个函数
VarPtrStringArray
VarPtrStringArray用于取得字符串数组的地址。为了避免VB 进行UNICODE/ANSI转换,
它的声明必须在类型库中定义
你也可以使用midl编译器将下面的.odl文件编译成你自己的类型库 :)
如果是Visual Basic 5.0,建立一个文本文件名为VB6ptrlib.odl,内容如下:
#define RTCALL _stdcall
[
uuid(C6799410-4431-11d2-A7F1-00A0C91110C3),
lcid (0), version(6.0), helpstring("VarPtrStringArray Support for VB6")
]
library PtrLib
{
importlib ("stdole2.tlb");
[dllname("msvbvm60.dll")]
module ArrayPtr
{
[entry("VarPtr")]
long RTCALL VarPtrStringArray([in] SAFEARRAY (BSTR) *Ptr);
}
}
如果是Visual Basic 5.0,建立一个文本文件名为VB5ptrlib.odl,内容如下:
#define RTCALL _stdcall
[
uuid(6E814F00-7439-11D2-98D2-00C04FAD90E7),
lcid (0), version(5.0), helpstring("VarPtrStringArray Support for VB5")
]
library PtrLib
{
importlib ("stdole2.tlb");
[dllname("msvbvm50.dll")]
module ArrayPtr
{
[entry("VarPtr")]
long RTCALL VarPtrStringArray([in] SAFEARRAY (BSTR) *Ptr);
}
}
在命令行使用MIDL编译器编译.ODL文件建立一个VB5或VB6的类型库(.TLB)
MIDL /t VB6ptrlib.odl
MIDL /t VB5ptrlib.odl
为了使用VarPtrStringArray你需要引用这个类型库
例子:
Dim MyArrayOfStrings(2) As String
Dim AddressOfArray As Long
MyArrayOfStrings(0)="AAA"
MyArrayOfStrings(1)="BBB"
AddressOfArray = VarPtrStringArray ( MyArrayOfStrings() )
ObjPtr
ObjPtr返回一个object变量的地址
objCollection.Add MyObj1, CStr(ObjPtr(MyObj1))
...
objCollection.Remove CStr(ObjPtr(MyObj1))