Lars
Lars

Reputation: 3

Fixed memory allocation for user defined types in vba

i have a User defined type in VBA (Excel) and want to have a fixed memory layout for the members so that I can use pointers in a later step for accessing those members.

The user defined type is looking like the code provided and I need to pass on the adresses of the members to a different programm.

I expected VBA to structere the members in the order that they are initialized but somehow it doesn't.

If you have any idea on how to solve that problem I would be really grateful!

Best Regards, Lars

Public Type ExampleSet

Example_P_Anteil                 As Single
Example_I_Anteil                 As Single
Example_D_Anteil                 As Single
Example_v0                       As Double
Example_Gang0                    As Integer
Example_Beschleunigung           As Double
Example_Startzeit                As Double

Example_int1                     As Integer
Example_int2                     As Integer
Example_int3                     As Integer

End Type

Upvotes: 0

Views: 532

Answers (1)

Mathieu Guindon
Mathieu Guindon

Reputation: 71187

I challenge your conclusions.

Public Type TestUDT
    SomeInteger As Integer ' Int16 (I2) at offset 0, padded with 2 bytes
    SomeLong As Long       ' Int32 (I4) at offset 4, no padding
    AnotherLong As Long    ' Int32 (I4) at offset 8, no padding
End Type

Public Sub test()
    Dim udt As TestUDT
    Debug.Print VarPtr(udt)             'expected: X
    Debug.Print VarPtr(udt.SomeInteger) 'expected: X+0
    Debug.Print VarPtr(udt.SomeLong)    'expected: X+4
    Debug.Print VarPtr(udt.AnotherLong) 'expected: X+8
End Sub

Output is as expected:

 723094616 
 723094616 
 723094620 
 723094624 

User-Defined Types (UDT) are defined in the language specifications as:

A linear concatenation of the aggregated data values possibly with implementation defined padding between data values.

The padding might be what's throwing you off, but a UDT is still a linear concatenation of its members.

Use the LenB function to determine the length of a member (or of the UDT as a whole):

Dim foo As ExampleSet
Debug.Print VarPtr(foo), LenB(foo)

If the UDT contains strings, define them as fixed-length if the offsets of the members that follow it need to be fixed:

Public Type TestUDT
    SomeString As String * 10
    '...
End Type

That said, good luck accessing these pointers out of process.

Upvotes: 4

Related Questions