Re: How to use program to detect struct is contiguous memory or not ?
The structure is always contiguous, VB just hides stuff.
In Type_a2, behind the scenes it's
a1 As Long
PointerToA2 As Long
a3(15) As Byte
You could recover the contents of a2 directly from memory;
Code:
Private Type SAFEARRAY1D
cDims As Integer
fFeatures As Integer
cbElements As Long
cLocks As Long
pvData As Long
cElements As Long
lLbound As Long
End Type
Dim ptr As Long
Dim sa As SAFEARRAY1D
CopyMemory ptr, ByVal VarPtr(Type_a2_var) + 4, 4
CopyMemory sa, ByVal ptr, LenB(sa)
Dim FirstElement As Long
'Assuming it's since been initialized
CopyMemory FirstElement, ByVal sa.pvData, 4
There's no good way to tell if an arbitrary member is in fact a pointer; you need to know what the structure represents.
Last edited by fafalone; Aug 1st, 2022 at 07:03 AM.
Re: How to use program to detect struct is contiguous memory or not ?
You could serialize it (through a pipe or just write it to a file) and check the serialized size with the UDT's size.
EDIT: That wouldn't necessarily work though if it had fixed length strings in it, as they're Unicode in the UDT, and they're ANSI after serialized. So you'd also have to account for that.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: How to use program to detect struct is contiguous memory or not ?
OP is basically asking how can he know if all the data in a structure is stored at the address of the structure variable. The answer is simple, if there are no variable length Strings and arrays and no object type members then all the data is stored contiguously in one place.
Code:
Private Type T
a As Byte
b As Boolean
c As Integer
d As Long
e As Date
f As Single
g As Currency
h As Double
i As String * 10
j(0 To 9) As Byte
End Type
As long as a structure contains only the types declared above, then the data is all in one place.
Code:
Private T2
a() As Byte
b As String
c As Object
End Type
If a structure contains any of the above types, then it will no longer be all in one place. Each of those types will be represented by a pointer to the actual data which resides elsewhere.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
Re: How to use program to detect struct is contiguous memory or not ?
@Niya: Ahh, yes, if that's all he wants to know, then yeah. The only thing that puts "pointers" into a UDT are "dynamic arrays", "variable length (BSTR) strings", and objects.
I thought he was asking about the item spacing issue, which is entirely different.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: How to use program to detect struct is contiguous memory or not ?
Originally Posted by Elroy
@Niya: Ahh, yes, if that's all he wants to know, then yeah. The only thing that puts "pointers" into a UDT are "dynamic arrays", "variable length (BSTR) strings", and objects.
Variant-Members (which will occupy 16Bytes in a given UDT, instead of 4) -
can contain all kind of Pointer-Types as well (even other UDTs).
Re: How to use program to detect struct is contiguous memory or not ?
Originally Posted by Schmidt
Variant-Members (which will occupy 16Bytes in a given UDT, instead of 4) -
can contain all kind of Pointer-Types as well (even other UDTs).
Good point. The rules are pretty much the same though, dynamic arrays, variable length strings, and objects ... with the addition of TypeLib declared UDTs in the Variants. And, just to say it, a UDT within a UDT (not in a Variant) is just expanded into the parent UDT (and doesn't use a pointer).
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: How to use program to detect struct is contiguous memory or not ?
Originally Posted by Niya
OP is basically asking how can he know if all the data in a structure is stored at the address of the structure variable. The answer is simple, if there are no variable length Strings and arrays and no object type members then all the data is stored contiguously in one place.
yes
I mean type members is stored contiguously in one place ( no any other pointer )
Re: How to use program to detect struct is contiguous memory or not ?
Originally Posted by quickbbbb
yes
I mean type members is stored contiguously in one place ( no any other pointer )
Yes, we did answer that question ... any variable length (BSTR) strings, any objects, or any dynamic arrays (as well as Variants with those as well as Variants containing UDTs) will only be pointers in the UDT. All else (including nested UDTs) will be within the actual UDT.
Originally Posted by dilettante
DWORD alignment through padding is another factor.
Yeah, that's what I mistakenly thought he was talking about.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: How to use program to detect struct is contiguous memory or not ?
Will the struct defs as text be available to your program ?
Are you trying to work on arbitrary structures without knowing the expected defs at all?
Are you only working in your own process address space of your own process?
Assuming the second scenario..if you don’t know the structure def there are things you can try but
It won’t be reliable. At a min you would need to know expected structure size, then you could scan for
What look like pointers to live memory, but it’s not really valid as longs extracted could cross data fields.
If you have access to the text of struct def then you could write a parser for yes/no
If the structures were all defined in an activex dll typelib then you could use tlbinf32 as your parser
In your own or another process heuristics would need to know entire process memory map if scsnning for pointers
Ultimately this only makes sense for dev time understanding of structs.
Unknown structs from a running process like for a game cheat, you won’t have perfect knowledge even by eye you would have to manually inspect memory and follow pointers and see what’s there and how data is being used,
This question can’t be answered without knowing why and what your trying to process and the env your working in,
It’s best to just assume it’s not continuous and serialize it to extract it. But this only works if it’s your own struct.
Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?
You know come to think of it, this question isn't all that strange. If this were asked on the VB.Net side of the forum, he'd have a clear yes as the answer. In VB.Net you could use reflection to enumerate all the members of a structure and if any of them were not primitives then you would know that the structure contains pointers.
I recall the trick mentioning on more than one occasion that reflection is also possible in VB6. It just requires a bit of wizardry.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?
Originally Posted by quickbbbb
my ask is "How to use program to detect" not "use eye to detect"
Wait, you want a programmatic way to detect if a UDT has a BSTR string, object, and/or dynamic array in it ... without knowing anything about the UDT?
NO, I don't think there's going to be a way to do that. If the UDT was in a TypeLib, you might be able to examine the TypeLib. But a standard UDT declared in VB6 code, not possible ... unless you assume you know something about it. Then you can check to see if any of the pointers (BSTR, object, dynamic array) are non-zero.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?
Originally Posted by Niya
this question isn't all that strange
If I could do this, my cLargeArrayUDT could validate whether the particular UDT can be stored there or not.
Now I had to leave that for the understanding of the programmer with my comment:
Another thing to consider is that the UDT must not have pointers, it means not variable arrays, variable size strings, variants or objects.
I have no idea if quickbbbb's question has to do with that, but it is a lot of coincidence (not every day someone would like to know if an UDT declaration implies pointers, but coincidences sometimes happen).
Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?
All the public UDTs fall to typelibraries so you can check all the fields or use the OLE-IRecordInfo implementation to manage UDTs. The same is for the public object-modules/enums.
Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?
Originally Posted by Eduardo-
I have no idea if quickbbbb's question has to do with that, but it is a lot of coincidence (not every day someone would like to know if an UDT declaration implies pointers, but coincidences sometimes happen).
It's not actually an unusual request. We do stuff like this quite a bit in the .Net world. As a matter of fact, certain serialization mechanisms in the .Net Framework rely on being able to perform operations like this to function properly. I've also seen Python code that perform type reflection similar to this to make certain things easier for developers using certain libraries. For example, the Odoo platform has an ORM layer that takes types declared in Python and builds database tables from these types. Being able to get information about structures and types declared in source code is pretty common place in 2022.
Originally Posted by The trick
All the public UDTs fall to typelibraries so you can check all the fields or use the OLE-IRecordInfo implementation to manage UDTs. The same is for the public object-modules/enums.
Perhaps it's about time someone provides an easy-to-use reflection library for VB6 programmers. This is the kind of thing I'd do for fun as a side project but all this COM stuff is way over my head. Nonetheless, there is so much one can do with reflection. Things like ORM and more robust serialization are among the things made possible by reflection. I mean these things are possible without reflection but with reflection, it's just so much better.
Personal example, I once wrote a binary protocol for Winsock that used structures to pass messages back and forth. Reflection made it so when I wanted to add a new message type, all I had to do was define the structure in the source code with a specific attribute and the infrastructure automatically would know of it's existence and how to deal with it.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?
This is a small example of serialization of a public UDT (with the references types) to an array:
Code:
Public Type TMySubUDT
o As Variant
b() As Byte
End Type
Public Type TMyUDT
l As Long
b As Byte
s As String
q() As Variant
k As Object
t As TMySubUDT
End Type
Code:
' //
' // UDT serialization snippet
' // by The trick
' //
Option Explicit
Public Enum PTR
[_]
End Enum
Public Const NULL_PTR As Long = 0
Private Declare Function vbaObjSetAddref Lib "msvbvm60.dll" _
Alias "__vbaObjSetAddref" ( _
ByRef dstObject As Any, _
ByRef srcObjPtr As Any) As Long
Private Declare Sub memset Lib "kernel32" _
Alias "RtlFillMemory" ( _
ByRef Destination As Any, _
ByVal Length As Long, _
ByVal Fill As Byte)
Private Declare Sub GetMemPtr Lib "msvbvm60.dll" _
Alias "GetMem4" ( _
ByRef addr As Any, _
ByRef retVal As Any)
Sub Main()
Dim tUDT As TMyUDT
Dim vUDT As Variant
Dim cRecInf As IRecordInfo
Dim cTMshl As ITypeMarshal
Dim pRecInf As PTR
Dim bData() As Byte
Dim lSizeData As Long
vUDT = tUDT ' // Obtain IRecordInfo
GetMemPtr ByVal VarPtr(vUDT) + 12, pRecInf
vbaObjSetAddref cRecInf, ByVal pRecInf
Set cTMshl = cRecInf
' // Init UDT
With tUDT
.s = "Hello!"
.l = 12345
.b = 255
Set .k = New Collection
.t.o = "Variant string"
ReDim .t.b(200)
.t.b(0) = 1
.t.b(1) = 2
.t.b(2) = 3
ReDim .q(5)
.q(0) = "Test string"
.q(1) = 987654
Set .q(2) = App
End With
' // Serialize UDT to byte array
lSizeData = cTMshl.Size(tUDT, MSHCTX_INPROC, ByVal NULL_PTR)
ReDim bData(lSizeData - 1)
lSizeData = cTMshl.Marshal(tUDT, MSHCTX_INPROC, ByVal NULL_PTR, lSizeData, bData(0))
ReDim Preserve bData(lSizeData - 1)
' // Deserialize UDT from byte array
Dim tOut As TMyUDT
Debug.Print cTMshl.Unmarshal(tOut, &H100000, lSizeData, bData(0))
Debug.Print tOut.s, StrPtr(tOut.s), StrPtr(tUDT.s)
' // Free first instance
cTMshl.Free tUDT
' // Safe zeroing
memset ByVal VarPtr(tUDT), LenB(tUDT), 0 ' // Avoid UNICODE <> ANSI
End Sub
Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?
Originally Posted by Eduardo-
Unfortunately, UDT's are most of the time declared private.
VB6 already has the restricted type description for the private UDTs (it's used for UDT copying) but as far as i remember there is no way to match a type descriptor to the UDT after compilation.