- pointer to the real or virtual element: @array(0, 0,...)
- pointer to the first real element: @array(lbound1, lbound2,...)
- "global" size in bytes: (ubound1-lbound1+1)*(ubound2-lbound2+1).....*(size of 1 element)
- size of one element in bytes
- number of dimensions
then for each dimension:
- number of elements: (ubound-lbound+1)
- lbound
- ubound
For the local fix-len arrays:
- the descriptor is just ahead the array elements,
- so from the address of the first array element, we can traced back directly to the structure of the descriptor.
For the global or var-len arrays:
- the descriptor is elsewhere in memory,
- so there is no direct way to access the descriptor.
For all types of array, there is a workaround to get the address of the descriptor (for 64-bit, compile with '-exx'):
- when an array is passed to a procedure, its descriptor is passed by reference,
- Just divert this parameter passing to retrieve the address of the descriptor in a generic Function(As Any Ptr) and return this as function return value.
- one macro allows to cast the function pointer depending on the array datatype.
Generic Function: 'arrayDescriptorPtrFunction (Byval p As Any Ptr) As Any Ptr'
Macro: 'arrayDescriptorPtr(array)'
Code: Select all
Function arrayDescriptorPtrFunction (Byval p As Any Ptr) As Any Ptr
Return p
End function
#Define arrayDescriptorPtr(array) _
Cast(Function (() As Typeof((array))) As Any Ptr, @arrayDescriptorPtrFunction)(array())
Code: Select all
Function arrayDescriptorPtrFunction (Byval p As Any Ptr) As Any Ptr
Return p
End function
#Define arrayDescriptorPtr(array) _
Cast(Function (() As Typeof((array))) As Any Ptr, @arrayDescriptorPtrFunction)(array())
'------------------------------------------------------------------------------------
Sub printArrayDescriptor (Byval p As Any Ptr)
Dim As Integer Ptr pu = p
Print "[@array descriptor: "; pu; "]"
Print " @array(all_null_indexes) ="; pu[0]
Print " @array(all_min_indexes) ="; pu[1]
Print " array_total_size_in_bytes ="; pu[2]
Print " array_element_size_in_bytes="; pu[3]
Print " number_of_array_dimensions ="; pu[4]
For i As Integer = 1 to pu[4]
Print " [dimension number:"; i; "]"
Print " number_of_elements="; pu[5 + (i - 1) * 3]
Print " min_index ="; pu[6 + (i - 1) * 3]
Print " max_index ="; pu[7 + (i - 1) * 3]
Next i
End Sub
'------------------------------------------------------------------------------------
Dim As Longint test1(0 to 9, 1 to 100)
Dim Shared As Longint test2(0 to 9, 1 to 100)
Dim As Longint test3()
Dim Shared As Longint test4()
Type UDT
Dim As Longint test1(0 to 9, 1 to 100)
Dim As Longint test2(Any, Any)
End Type
Dim As UDT u
Screen 0
Width , 30
printArrayDescriptor(arrayDescriptorPtr(test1))
Sleep
Cls
printArrayDescriptor(arrayDescriptorPtr(test2))
Sleep
Cls
printArrayDescriptor(arrayDescriptorPtr(test3))
Print
Redim test3(0 to 9, 1 to 100)
printArrayDescriptor(arrayDescriptorPtr(test3))
Sleep
Cls
printArrayDescriptor(arrayDescriptorPtr(test4))
print
Redim test4(0 to 9, 1 to 100)
printArrayDescriptor(arrayDescriptorPtr(test4))
Sleep
Cls
printArrayDescriptor(arrayDescriptorPtr(u.test1))
Sleep
Cls
printArrayDescriptor(arrayDescriptorPtr(u.test2))
print
Redim u.test2(0 to 9, 1 to 100)
printArrayDescriptor(arrayDescriptorPtr(u.test2))
Sleep
Used now 'Typeof((array))' (with double parentheses) to be compatible with array inside a Namespace (see #404).