|
-
Dec 13th, 2007, 09:04 PM
#1
Pointers in VB
People said "Unlike C, there is no 'pointer' in plain VB. Probably we need to use some API functions to access pointers."
I found 3 buit-in VB pointer functions: StrPtr(), VarPtr() and ObjPtr(), but they are undocumented.
Anyone has any information about them? It will be helpful for someone.
(I saw @vbasicgirl used one of these in a thread.)
-
Dec 13th, 2007, 09:19 PM
#2
Re: Pointers in VB
Sure, you can find some more details by googling too....
StrPtr. Value is the memory location where the actual string data/chars begin. 4bytes before that memory location is the length of the string.
Code:
Dim s As String, I As Integer, J As Long, L As Long
s="Hi"
CopyMemory I, ByVal StrPtr(s), 2&
CopyMemory J, ByVal StrPtr(s)+2, 2&
CopyMemory L, ByVal StrPtr(s)-4, 4&
Debug.print s,chr$(i);chr$(j)," Length=";L
Try this: StrPtr(vbNullString), StrPtr("")
VarPtr. Memory location where the variables contents can be found. This may be another pointer or it could be the actual variable's value. For example... The value found at memory address: VarPtr(stringSomething)= StrPtr(stringSomething) which points to the string data.
Code:
Dim X as Long, V As Long, S As String
s="Hi"
CopyMemory V, ByVal VarPtr(s), 4&
Debug.Print "StrPtr(s)="; StrPtr(s); " Value at VarPtr(s) is ";V
X=1962&
CopyMemory V, ByVal VarPtr(X), 4&
Debug.Print "X=";x; " Value at VarPtr(x) is "; V
ObjPtr relates to stuff associated with Set commands, forms, controls, classes, etc, etc. It won't do you much good unless you are very familiar with the structure of what it is pointing too. But one neat test that can be performed.
Code:
Dim tPic As stdPicture
Debug.Print "tPic is Nothing & ObjPtr(tPic)="; ObjPtr(tPic) ' should be zero
Set tPic = New stdPicture
Debug.Print "tPic is not Nothing & ObjPtr(tPic)="; ObjPtr(tPic) ' should NOT be zero
' Note: ObjPtr is often used to create unreferenced copies of objects from a
' previously cached ObjPtr() value...
' When using Set tPic = oldPic, the reference count on oldPic is incremented
' and then when Set tPic = Nothing the count is decremented & when the
' count = 0& the object is destroyed. By using a statment like:
Dim tmpObj As Object, oPtr As Long
Set tPic = Me.Icon
oPtr = ObjPtr(tPic)
CopyMemory tmpObj, oPtr, 4&
Debug.Print "tPic Pointer & Handle is "; ObjPtr(tPic); tPic.Handle; " tmpPic Pointer & Type is "; ObjPtr(tmpObj); tmpObj.Handle
' tmpObj is same as tPic but the reference count wasn't incremented.
' This has the nasty effect of crashing if the tmpObj isn't cleared before
' tPic is destroyed: Cleared as shown below
CopyMemory tmpObj, 0&, 4&
One can go on & on having fun. Careful though, CopyMemory if using invalid values or using ByRef/ByVal incorrectly can crash your app & possibly windows. Here is the declaration I used:
Code:
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Last edited by LaVolpe; Dec 13th, 2007 at 10:00 PM.
-
Dec 13th, 2007, 10:14 PM
#3
Re: Pointers in VB
Oh there is another pointer some are not familiar with: array pointers, but VB doesn't expose it without API usage.
Code:
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (ByRef Ptr() As Any) As Long
' Example:
Dim myArray(0 To 10) As Long
Dim aPtr As Long, aFarPtr As Long
aFarPtr = VarPtrArray(myArray)
CopyMemory aPtr, ByVal aFarPtr, 4&
Debug.Print "SafeArray pointer for myArray() is "; aPtr
' P.S. If aPtr above is zero, the array is not initialized
' Try it. Change to Dim myArray() As Long
' the pointer to the 1st item in the array is VarPtr(myArray(0))
This pointer points to a pointer to a SafeArray structure. SafeArray structures are well documented
Last edited by LaVolpe; Dec 13th, 2007 at 11:45 PM.
-
Dec 14th, 2007, 01:44 AM
#4
Re: Pointers in VB
You can also use AddressOf SubOrFunctionName to pass a function pointer to a procedure. Then there is the Not operator for getting a pointer to the beginning of safearray structure:
Code:
Option Explicit
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (ByRef Ptr() As Any) As Long
Private Sub Form_Load()
Dim lngArray1(9) As Long, lngArray2() As Long, lngArray3() As Long
ReDim lngArray2(9)
Debug.Print Not Not lngArray1, VarPtrArray(lngArray1), "Fixed array"
Debug.Print Not Not lngArray2, VarPtrArray(lngArray2), "Variable length array"
Debug.Print Not Not lngArray3, VarPtrArray(lngArray3), "Uninitialized array"
Debug.Print CLng(1#) ' <- and this is the infamous P-code bug that happens when you use Not Array...
End Sub
To workaround the bug so you can have floating point math in IDE without annoying error messages:
Code:
Debug.Print Not Not lngArray1
On Error Resume Next: Debug.Assert CLng(0#): On Error GoTo 0
Last edited by Merri; Dec 14th, 2007 at 12:50 PM.
-
Dec 14th, 2007, 09:32 AM
#5
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|