如何在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))  
  
  
   
 
  |