Re: VarPtr strange result
Issue similar to double() in a variant. It was left unanswered. It seems VarPtr doesn't work as expected for arrays in a variant. Try assigning values to the array and you'll see that both results, 0 and 16387, were actually garbage.
Re: VarPtr strange result
Also, try debug printing VarPtr of other array elements... VarPtr(v1(0)) = VarPtr(v1(1)) = VarPtr(v1(2)) ... it doesn't work, how it came up with 1308228 (or why that particular value was returned) for all array elements remains to be answered.
Re: VarPtr strange result
I don't know why it does that but I can see what it's doing in part. The 1308228 appears to be an address of a variant. The 16387 is the first two bytes of a variant, it indicates that the variant holds a pointer to a long (16384=contains pointer, 3=Long). Try assigning a value to V1(0) and then use the code below
Code:
CopyMemory L1, ByVal p1 + 8, 4
CopyMemory L1, ByVal L1, 4
CopyMemory L2, ByVal VarPtr(v1(0)) + 8, 4
CopyMemory L2, ByVal L2, 4
Debug.Print L1, L2, v1(0)
The strange part for me is why when you use Byval P1 the first two bytes of the variant are missing? The rest of the variant is exactly the same.
Re: VarPtr strange result
Quote:
Originally Posted by Milk
it indicates that the variant holds a pointer to a long (16384=contains pointer, 3=Long).
Where did you find that 16384 means pointer? Is there a web reference you can post?
Re: VarPtr strange result
I could not find any reference I'm afraid but testing showed it to be pretty consistent.
The first byte indicates the data type, the second seems to indicate what is stored in the data section of the Variant structure.
The second byte always seems to be one of four values...
00 - The variant contains the variable data (in the case of a Pointer based data types like String and Object this data is a pointer)
32 - As documented in MSDN this is the vbArray type, got to look at exactly what this means, I suspect it indicates an array of variants. (your original post seems to demonstrate this)
64 - The variant contains a pointer to the variable data
96 - The variant contains a pointer to a pointer to a SafeArray structure (same as the return for VarptrArray)
One thing I did notice today is that there is a big difference between assigning a variable to a variant and passing a variable as a variant. I'm going to look at this in more detail later.
I also keep seeing the odd thing that talks of a 22 byte char variant, but I've not been able to create one of these.
Re: VarPtr strange result
Quote:
Originally Posted by Milk
I could not find any reference I'm afraid but testing showed it to be pretty consistent. The first byte indicates the data type, the second seems to indicate what is stored in the data section of the Variant structure.
The second byte always seems to be one of four values...
64 - The variant contains a pointer to the variable data
I see your point. Seems to work as you indicate for arrays of most data types, but it breaks down if variant() is used. This is v-e-r-y strange...
Code:
Dim L1 As Integer
Dim v1 As Variant
Dim b1 As Byte, b2 As Byte
Dim a(1) As Long
Dim b(1) As Double
Dim c(1) As Byte
Dim d(1) As Single
Dim E(1) As Boolean
Dim F(1) As String
Dim G(1) As FileDialog
Dim H(1) As Single
Dim I(1) As Integer
Dim J(1) As Variant
v1 = I
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbInteger; "Integer", vbInteger, b1, b2
v1 = a
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbLong; "Long", , vbLong, b1, b2
v1 = d
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbSingle; "Single", vbSingle, b1, b2
v1 = b
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbDouble; "Double", vbDouble, b1, b2
v1 = F
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbString; "String", vbString, b1, b2
v1 = G
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbObject; "Object", vbObject, b1, b2
v1 = E
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbBoolean; "Boolean", vbBoolean, b1, b2
v1 = c
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbByte; "Byte", , vbByte, b1, b2
v1 = J
CopyMemory L1, ByVal VarPtr(v1(0)), 2
CopyMemory b1, ByVal VarPtr(v1(0)), 1
CopyMemory b2, ByVal VarPtr(v1(0)) + 1, 1
Debug.Print VarPtr(v1(0)); L1; L1 - vbVariant; "Variant", , vbVariant, b1, b2
' 1307968 16386 16384 Integer 2 2 64
' 1307968 16387 16384 Long 3 3 64
' 1307968 16388 16384 Single 4 4 64
' 1307968 16389 16384 Double 5 5 64
' 1307968 16392 16384 String 8 8 64
' 1307968 16393 16384 Object 9 9 64
' 1307968 16395 16384 Boolean 11 11 64
' 1307968 16401 16384 Byte 17 17 64
' 195686664 0 -12 Variant 12 0 0
Re: VarPtr strange result
Your strange result is because V1(0) is an empty variant... 16 bytes of zero.
195686664 can't be a valid address can it? It would be way off the stack. I've no idea why Varptr appears to be failing in this case.
Try this
Code:
v1 = J
'v1(0) = "hello" '<--- toggle this
CopyMemory L1, v1(0), 2
b1 = L1 And 255
b2 = L1 \ 256
Have a look at the other Variant thread you started, the code I posted has had no problems (so far) with any variant I've thought to throw at it (including public udt's)