Tools Links Login

Trick VB into making small bit arrays by controlling its array management

Replace the array descriptor that VB uses with your own descriptor structure, and make it point to your data. Here is an example that forces VB to create an array of bytes that only takes 2 bytes per array element instead of 6, plus the descriptor size. Lots of comments. Please don't forget to vote!

Original Author: Xavier Harel

Code

'Paste all this in the form code of a new project, run it, and step into it to follow the process:
' This is a redeclaration of VB's VarPtr that forces it to return the address of the array descriptor structure:
Private Declare Function GetArrayPtr Lib "msvbvm60.dll" Alias "VarPtr" ( _
Ptr() As Any _
) As Long
' This is a translation into VB code of C++'s safearray descriptor structure:
Private Type SafeArrayBound
lNumOfElements As Long
lLowBound As Long
End Type
Private Type SafeArr
iDimensions As Integer
iFeatures As Integer
lElementSize As Long
lLocks As Long
lDataPtr As Long
saBound(0) As SafeArrayBound
End Type
Private Const FADF_AUTO = &H1 ' Array is allocated on the stack.
Private Const FADF_FIXEDSIZE = &H10 ' Array may not be resized or reallocated.
Private Sub FillMyBytesArray()
Dim Bytes() As Byte ' creates an array descriptor of type SafeArr pointing to no data
Dim sMyString As String ' will hold data that I'll use as the data that Bytes() is pointing to
Dim aMySAB(0) As SafeArrayBound
Dim aMySA As SafeArr
Dim sResult As String
Dim i As Integer
sMyString = "This is a relatively short string"
' create the descriptor that will replace the Bytes() array descriptor declared above
With aMySAB(0) ' Description of an array dimension (size and lbound)
' the string is stored as unicode, which means that the 1st word is stored as "T" + chr(0) + "h" + chr(0) + "i" + chr(0) + "s" + chr(0)
' so that there are really twice as many bytes stored as the length of the string:
.lNumOfElements = 2 * Len(sMyString) ' number of elements in this array dimension
.lLowBound = 0 ' specifies the array's Lbound value
End With
With aMySA
' this is a 1-dimension byte array:
.iDimensions = 1
.lElementSize = 1 ' size of each element
.iFeatures = FADF_AUTO Or FADF_FIXEDSIZE ' Flags that enable array features.
.lDataPtr = VarPtr(ByVal sMyString) ' make the descriptor point to the declared string data. ByVal is VERY important.
.saBound(0) = aMySAB(0) ' describes each dimension of the array, in this case only one.
End With
' move the memory contents of the descriptor to the address of the Bytes() array descriptor, the ByVal is VERY important if you don't want to overwrite memory and risk a crash!
CopyMemory ByVal GetArrayPtr(Bytes), VarPtr(aMySA), 4
' Reattach all the bytes together to reconstruct sMyString. Notice that Bytes() now has data, and that there is no error calling Ubound(Bytes):
For i = 0 To UBound(Bytes)
sResult = sResult & Chr(Bytes(i))
Next i
' Since we read the string data directly from memory, we have unicode, and we have to disregard all odd array indexes, or convert the result string from unicode:
sResult = StrConv(sResult, vbFromUnicode)
' now sResult contains the same data as sMyString.
End Sub
Private Suv Form_Load()
FillMyBytesArray ' call the sub above
End Sub
' I will post more on this topic if it becomes popular

About this post

Posted: 2002-06-01
By: ArchiveBot
Viewed: 73 times

Categories

Visual Basic 6

Attachments

No attachments for this post


Loading Comments ...

Comments

No comments have been added for this post.

You must be logged in to make a comment.