Getting confused with VBA and VB addresses and pointers.
Taking a time out here to ask a question or two or 11 over at Eileen's Lounge
https://eileenslounge.com/viewtopic....323893#p323893
https://eileenslounge.com/viewtopic....323894#p323894
Here is the two post in one…….
Hi
I have been going around in circles on this one for a few days, and I am still not sure if I have quite got it right.
Can someone help put me out of my misery by confirming some things or otherwise….
First, I think I do understand approximately how a VBA Long type variable and a VBA String type variable are handled in memory, and I think I understand the important differences in those two, ( and why) , in the way they are handled and stored. My confusion is related to exactly which memory addresses are being referred to in the following coding examples
Long example
Code:
Sub ConfusedWithVBALongTypeMemoryStuff()
1 Dim Lng As Long
2 Debug.Print VarPtr(Lng) ' 2355700 I don't know where this number is held in memory. I don't care
3 Debug.Print VarPtr(ByVal Lng) ' 0
4 Debug.Print Lng ' 0
Let Lng = 2
5 Debug.Print VarPtr(Lng) ' 2355700
6 Debug.Print VarPtr(ByVal Lng) ' 2
8 Debug.Print Lng ' 2
End Sub
In the first line of the coding above, Dim Lng As Long , Lng becomes a number which is made with 4 bytes, (32 bits). It is called a Pointer. The actual number refers to the first memory address ( the first memory address at the left hand side) of 4 Bytes (32 bits) set aside in memory to hold the final value which I later assign to the variable, (with Let Lng = 2 ). In other words, the act of doing Dim Lng As Long reserves for me 4 sequential memory addresses/ byte locations, in a sequential row as it were. And the first one, the first byte, at the left as it were, has the memory location got for me with the second code line, Debug.Print VarPtr(Lng) (by me , I got the value shown in the ' comment - 2355700** )
Q1: Have I got that right?
The third line, Debug.Print VarPtr(ByVal Lng) , is perhaps giving me the same as the 4th line, which is the value of the variable. For the case of a Long Type it does have a value even before I assign one. It has the value 0. If I assigned it 0 with Let Lng = 0 nothing would change anywhere
Q2: Have I got that right?
In line 5 , the memory location has not changed, as it never does for the VBA Long type, even if I assign a much different number. This is because It doesn’t need to change, because 32 bits are enough to hold in binary any number in the range of the defined number range for a VBA Long type
Q3: Have I got that right?
Line 6 aqnd line 8: My results suggest that Debug.Print VarPtr(ByVal Lng) and Debug.Print Lng are giving me the same thing – the value it sees at the address, 2355700**.
Q4: Any comments at all on that?
( **The address I got was 2355700 , you will get a similar but different number. I am OK with that and understand why that is )
This next bit is what has got me a bit confused. The 32 Bit number, the number returned from the second code line, Debug.Print VarPtr(Lng) , (by me 2355700** ) , is presumably held somewhere in memory as well? Where I don't know (I am not complaining, I just am trying to confirms that I got that right). I know the value held there, (by me 2355700** ) , but I don’t know where that number is being held
Q5: Have I got that right? (I expect VarPtr( ) knows that memory location as it goes there and gets the number in it for me. ( Maybe there is a "stack" of active variables and their values somewhere we ain't privy to?)
Q6: In this situation what is actually the "Pointer". Is it
_ the number the second code line, Debug.Print VarPtr(Lng) , gets me,
_ is it the variable Lng ,
_ is it the Bytes used for it somewhere I don't know?
Or is the word "pointer" some vague concept you would use to refer to one or more of those things or all of them depending on the context in which you use it
I have some similar questions on the VBA String type. It will perhaps help tidiness and later reference if I do another post for that…..
Ref: VarPtr , StrPtr stuff https://classicvb.net/tips/varptr/ , https://www.vba-tutorial.de/referenz/zeiger.htm
https://www.excelfox.com/forum/showt...age3#post11886
Unicorn or Unicode Encoding – A beast by any name
…….. continued, sort of, from last post
…. Confused with VBA and VB String Pointer Stuff
First, I do understand
_ (i) that String memory handling generally in computing, is a bit more dynamic/ complex than something like for a simple number, since even with modern computers, we don’t want to go around reserving a Giga Byte or two of memory every time we Declare a string variable.
and
_(ii) thanks to a lot of research and help from here, I am pretty well clued up now on all the various Ascii Ansi, Unicorns and other character encoding beasts roaming about ..
Once again my main confusion just now is/ was to do with what memory addresses / pointers are referring to what / where etc…
So, bearing that in mind…..
and with reference to the coding below….
After a month on and off researching VB String stuff, and VBA – VB API stuff, I was not too sure anymore that I even understood the very first line, Dim Str As String, … but as is often the case, preparing carefully the question can often help get the answer… The second code line Debug.Print VarPtr(Str) actually returned me the very same number as the second code line in the coding from the last post, Debug.Print VarPtr(Lng)!! I do realise that will not always be the case, but as I ran the coding shortly after running the previous coding on the same computer, then there is a chance it will be the same, as it was, … because….. how about this: What Dim Str As String in the coding below is doing, is very similar to what the Dim Lng As Long did/does in the coduing from the last post, - it sets aside once again 4 Bytes (32 bits) for me. But the difference being now is that it is not reserving me a place to store any final number or character values, rather it is reserving me a place … for …. a 32Bit Pointer , specifically a pointer to a VB String, (what I might refer to as a COM BSTR), and if I am feeling very adventurous I might say it’s a LPWSTR pointer, (or variation of) , which means that when it eventually gets filled in, it will be the address not of the start memory point I finally use for my string, but rather 4 Bytes along where the actual Unicode UTF-16 LE encoding Bytes start.
Q7. Have I got that right?
So I could say, what I have is a VBA Pointer to a VB Pointer, or perhaps a VBA Pointer to what likely will be a VB Pointer – depending on how you feel the word pointer should be used
Q8. Have I got that right?
The result 0 of code line 3 and code lines 4 are, I think, telling me the bit I think I know, -they are telling me that, unlike in the case of the Long I have not yet reserved any memory for my final character string.
Q9a) Have I got that right?
Q9b) This is a tricky one that might get me hate mail. I am sure many people would tell me that at this point my Str variable is a vbNullString. I don’t see that. I think I have nothing to do with a VB string at this point? All I have is an empty VBA 32 bit pointer, possibly even indistinguishable from a Long variable of value 0
Any comments on that?
Q9c) I am not too clear what the difference is in these 2(3) code lines.
VarPtr(ByVal Str)
StrPtr(ByVal Str) ; StrPtr(Str)
It is discussed at the first of the references below, but I cannot quite understand what they are on about. Apparently the StrPtr( ) was introduced to make sure you go to the actual Unicode UTF-16 LE encoding Bytes start bit. (the 5th byte along ). But VarPtr(ByVal Str) seems to be doing this. Is this maybe VBA being a bit cleverer with the VarPtr( ) than VB is / was?
Q10 This is similar to Q5. The 32 bit address value/ number of the variable Str (by me 2355700** ) , is itself somewhere in memory. I don’t know where, that is to say I do not know the memory location holding that number . I don't particularly care. I am just wanting that confirmed.
Is that correct?
I think the rest of the coding makes sense to me. The VBA Pointer address generally does not change, (code line 5), the other 2(3) code lines 6 and 7 all do the same thing ( differences in what / how is Q9c). Although the 3 values are always the same value, that value will likely change every time you run the coding. I am OK with understanding what is going on there
( As for code line 8, that, and related VB API stuff, is the subject of another Thread I want to get back to, but I got a bit stuck on the issues I raised in this Thread, so later on that one. - Just passing interest, a taste of interesting things to come as it were, …. what we have in code line 8 is VBA knowing what's going on. VBA does a lot of heavy stuff for us. APIs in VBA on the other hand, can get a bit confused, … the poor old things can even get confused with VB strings more than half the time…. But we will soon have all that sorted as well, :) , :wink: :grin: :cool: )
String example coding
Code:
Sub ConfusedWithVBAandVBStringPointerStuff() ' https://www.excelfox.com/forum/showthread.php/2404/page3#post11886
1 Dim Str As String
2 Debug.Print VarPtr(Str) ' 2355700 I don't know where this number is held in memory. I don't care
3 Debug.Print VarPtr(ByVal Str) ' 0
4 Debug.Print StrPtr(ByVal Str); StrPtr(Str) ' 0 0
Let Str = "ABCD"
5 Debug.Print VarPtr(Str) ' 2355700 - makes sense - no reason for this address to change. It is the first Byte of the 4 bytes that holds the VB pointer/ address, whatever value that is
6 Debug.Print VarPtr(ByVal Str) ' 4028444
7 Debug.Print StrPtr(ByVal Str); StrPtr(Str) ' 4028444 4028444
8 Debug.Print Str
End Sub
Q 11. Is the following beautiful sketch an accurate technical depiction of the situation just before the above coding ends?
In that sketch I have enclosed 3 memory chunks, and I have, sort of , connected them with arrow/pointers:
, starting form the bottom there are two memory chunks of 4 Bytes.
The bottom I know what is in it but not where it is.
The middle one I know where it is and what is in it
The top enclosed memory chunk in this example is 14 bytes, ( it would be 18 Bytes if I had ABCDEF, and so on ).
https://i.postimg.cc/L6zbgmFC/A-VBA-...y-any-name.jpg
https://i.postimg.cc/zVGj9ZBK/A-VBA-...y-any-name.jpg
Thanks for any help, comments , confirmations etc
Alan
Ref: VarPtr , StrPtr stuff
https://classicvb.net/tips/varptr/
https://www.vba-tutorial.de/referenz/zeiger.htm
4 Attachment(s)
Stacks of Coffee tables Ideas
Buffer Post COFFee table ideas
This post reserved probably for Pallet stacking Ideas and Trendy COFFee tables made with norm dimensioned/size wooden Pallets
Arising from this
By definition a VBA Long is 32bits, So ... yes. But that's not why the memory location has not changed. I am not going to get into the Common Object File Format (COFF) and symbol tables here, but that provides you some nice new keywords to Google ... (but be warned, you are moving very much away from VBA here). This, by the way, is essentially the "... 'stack' of active variables and their values somewhere we ain't privy to?"
>_ the number the second code line, Debug.Print VarPtr(Lng) , gets me,
>_ is it the variable Lng
Lng is the symbol for the pointer,
VarPtr(Lng) gets you the value of the pointer, which is the memory address the pointer is pointing to
Lng itself is stored in the COFF symbol table
Note that one of the whole points of high-level languages is to (try to) hide this stuff away from you.
Snowy pisc, from this time of the year. - Impracticle conditions for Stacks of Coffee tables Ideas
Attachment 6150
https://i.postimg.cc/90WBwmMH/Beutif...xperiments.jpg
https://i.postimg.cc/90WBwmMH/Beutif...xperiments.jpg
Earlier Pics
Attachment 6151Attachment 6152Attachment 6149
https://i.postimg.cc/3JzKKdN6/Pooh-Bahnhof-im-Bau.jpg
https://i.postimg.cc/Zq8Ys4TQ/Pooh-Bahn-Hof-im-Bau.jpg
Team work
https://i.postimg.cc/m2mmMHCX/Stacking-Ideas.jpg
https://i.postimg.cc/7hySGvsp/Skematic-VBA-Long.jpg
https://i.postimg.cc/VLmjz8bt/Skematic-VBA-String.jpg