Я оспариваю ваши выводы.
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
Вывод соответствует ожидаемому:
723094616
723094616
723094620
723094624
Пользовательские типы (UDT) определены в спецификациях языка как:
Линейная конкатенация значений агрегированных данных, возможно, с заполнением, определенным реализацией между значениями данных.
Заполнение может быть тем, что вас отбрасывает, но UDTвсе еще линейная конкатенация его членов.
Используйте функцию LenB
, чтобы определить длину члена (или UDT в целом):
Dim foo As ExampleSet
Debug.Print VarPtr(foo), LenB(foo)
Если UDT содержит строки, определите их как фиксированную длину, если необходимо исправить смещения элементов, следующих за ним:
Public Type TestUDT
SomeString As String * 10
'...
End Type
Тем не менее, удачи в доступе к этим указателям вне процесса.