Anyone happen to know how I'd find out the length of an array of UDTs that I have ?
I need to so that I can pass a pointer and data length to a function...
Microsoft MVP : Visual Developer - Visual Basic [2004-2005]
That will not work for variable length strings and its LENB especially if its going to passed to an external DLL or function (I read Ur previous post Jamie)
One (and only one) of the two possible arguments must be specified. With user-defined types, Len returns the size as it will be written to the file.
Note Use the LenB function with byte data contained in a string, as in double-byte character set (DBCS) languages. Instead of returning the number of characters in a string, LenB returns the number of bytes used to represent that string. With user-defined types, LenB returns the in-memory size, including any padding between elements. For sample code that uses LenB, see the second example in the example topic.
Note Len may not be able to determine the actual number of storage bytes required when used with variable-length strings in user-defineddata types
"Brothers, you asked for it."
...Francisco Domingo Carlos Andres Sebastian D'Anconia
Since they are strings (OLECHAR or BSTR) you have to iterate thru the whole array and sum the lengths.
Except - that does not give the actual length of the UDT.
When you Dim ccc as String the actual variable is a quadword
in length. BSTR are actually string descriptors. The first longword is the address of string buffer, the second is the length.
The other problem is: VB converts all VB strings on calls to dll's to
null-terminated byte arrays (C-style char arrays). This is because most dll's are written in C and don't expect BSTR. And cannot deal with them either.
You are better off copying your UDT array into something else, another UDT array with fixed length byte arrays that you can quantify correctly.
Because Len needs an instance of the variable, not it's type...
I had that idea, but imagine this situation :
The array : systemInfo(0).hardwareInfo.PrintersInfo()
On systemInfo(0), that computer may have no printers, so that array is empty.
But on systemInfo(1), that computer might have 10 printers, so that array would be dimensioned.
So surely the datasize of systemInfo(0) would differ greatly to that of systemInfo(1) ?
Microsoft MVP : Visual Developer - Visual Basic [2004-2005]
You could have an interface class ISerialiseable that is like:
VB Code:
Option Explicit
Public Property Get DataSize() As Long
End Property
Then each class implements that i.e.:
VB Code:
'cPrintersInfo
Implements ISerialiseable
Public Property get ISerialiseable_DataSize() As Long
ISerialiseable_DataSize = 8
End property
And if a class includes a collection the it's implementation of ISerialiseable_DataSize iterates the collection getting their sizes and adding them to its.
But to see if things can be managed as is...................
The code below shows the length of the second UDT as 4. I presume its 'cause a pointer to the actual data is stored in the UDT. Would it be possible to get that pointer (do a memcopy) and read 4 bytes before that pointer to extract the length? I ask this as I understand that VB stores the length in memory as a "long" just before the begining of the actual data. At least that is the case with storage of variable length Strings in VB.
VB Code:
Private Type MYTYPE
strValue As String
intValue As Integer
End Type
Private Type AllTypes
udtAllTypes() As MYTYPE
End Type
Private Sub Command1_Click()
Dim myTypes(3) As MYTYPE, lngLength As Long, all As AllTypes
Same luck here . Should it not be an array of UDTs, it should be manageable even with variable length strings in a UDT. An array holds just one more set of pointers rather than any contiguous data.
Guess, U'll have to change Ur approach or do a disk dump.
"Brothers, you asked for it."
...Francisco Domingo Carlos Andres Sebastian D'Anconia
Originally posted by plenderj Well ill use a disk dump for development.
But i would much rather have a better implementation when the product goes live
... maybe I could use fibers...
Whats fibers?
"Brothers, you asked for it."
...Francisco Domingo Carlos Andres Sebastian D'Anconia
Anything non fixed length in a UDT has to be implemented by a pointer. Fixed length stuff is just held in a contiguous memory block.
So - with alltypes, the value in VarPtr(alltypes) is a pointer to the first MYTYPE. This in turn holds a pointer to a string (4 bytes) folowed by the integer itself (2 bytes) followed by the next one and so on.
You would be far better to go the classes / collections route IMO - you can even pass them between apps.
Also see if U could use the VBHELP32.DLL (attached). It had been used earlier to solve this issue, and there is a reference to handling arrays and variable length string in its help file.
I tried it with the code I posted above, but can't get it work. Hope U do.
Regards
KayJay
"Brothers, you asked for it."
...Francisco Domingo Carlos Andres Sebastian D'Anconia