Results 1 to 22 of 22

Thread: [RESOLVED] How to use program to detect struct is contiguous memory or not ?

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jun 2017
    Posts
    236

    Resolved [RESOLVED] How to use program to detect struct is contiguous memory or not ?

    Hi~ ALL

    How to use program to detect data in struct is contiguous memory or not ?

    '=====

    Private Type Type_a1
    '---> is contiguous memory
    a1 As Long
    a2(11) As Long
    a3 As String * 8
    End Type

    Private Type Type_a2
    '---> is not contiguous memory : because a2() As Long
    a1 As Long
    a2() As Long
    a3 As String * 8
    End Type

    Private Type Type_a3
    '---> is not contiguous memory : because a3 As String
    a1 As Long
    a2(11) As Long
    a3 As String
    End Type
    Last edited by quickbbbb; Aug 1st, 2022 at 07:43 PM.

  2. #2
    Hyperactive Member
    Join Date
    Mar 2019
    Posts
    414

    Re: How to use program to detect struct is contiguous memory or not ?

    It would help if, besides the question asked, to understand what problem you are trying to solve. I would guess something to do with copy memory?

  3. #3
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,647

    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.

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    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.

  5. #5
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    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.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    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

  6. #6
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    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.

  7. #7
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: How to use program to detect struct is contiguous memory or not ?

    Quote Originally Posted by Elroy View Post
    @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).

    Olaf

  8. #8
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How to use program to detect struct is contiguous memory or not ?

    Quote Originally Posted by Schmidt View Post
    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.

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    Jun 2017
    Posts
    236

    Re: How to use program to detect struct is contiguous memory or not ?

    Quote Originally Posted by Niya View Post
    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 )

  10. #10
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: How to use program to detect struct is contiguous memory or not ?

    DWORD alignment through padding is another factor.

  11. #11
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How to use program to detect struct is contiguous memory or not ?

    Quote Originally Posted by quickbbbb View Post
    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.

    Quote Originally Posted by dilettante View Post
    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.

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    Jun 2017
    Posts
    236

    Re: How to use program to detect struct is contiguous memory or not ?

    Quote Originally Posted by Elroy View Post
    Yes, we did answer that question
    my ask is "How to use program to detect" not "use eye to detect"

  13. #13
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,053

    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.
    Last edited by dz32; Aug 2nd, 2022 at 02:00 AM.

  14. #14

    Thread Starter
    Addicted Member
    Join Date
    Jun 2017
    Posts
    236

    Re: How to use program to detect struct is contiguous memory or not ?

    thank every one

  15. #15
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    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.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    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

  16. #16
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?

    Quote Originally Posted by quickbbbb View Post
    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.

  17. #17
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?

    Quote Originally Posted by Niya View Post
    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).

  18. #18

  19. #19
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?

    Quote Originally Posted by Eduardo- View Post
    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.

    Quote Originally Posted by The trick View Post
    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.
    Last edited by Niya; Aug 2nd, 2022 at 02:38 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    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

  20. #20
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: [RESOLVED] How to use program to detect struct is contiguous memory or not ?

    Unfortunately, UDT's are most of the time declared private.

  21. #21
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    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
    Attached Files Attached Files

  22. #22

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width