Results 1 to 33 of 33

Thread: Question about classes in VB6

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    Question about classes in VB6

    When you set an object variable to a class, it creates an instance of that class. That instance includes a a VTable with pointers to functions, and also a copy of any variables the class uses. What I'm not sure of is this. Does the class instance also contain a copy of the executable code that was initially stored in the base class? Or do the entries in the VTable in every instance always point to code in the base class?

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

    Re: Question about classes in VB6

    Hi Ben,

    I'm sure Olaf will chime in on this one, as he's quite the expert on COM, COM+, and class instantiation. However, it's my understanding that a single copy of the code is loaded on the first instantiation. Since the code is re-entrant, you'll only need one copy. However, all variables, including module level and statics, will have separate copies created.

    Hope That Helps,
    Elroy

    Also, when dealing with these COM objects, it's always important to differentiate between separate instantiations (separate instances), and aliases of the same instance. VB6 may not like aliasing of regular variables, but it trivially aliases any object.
    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.

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

    Re: Question about classes in VB6

    Quote Originally Posted by Ben321 View Post
    When you set an object variable to a class, it creates an instance of that class.
    Not true. What it does it assign a reference and increment the reference count.

    And "base class" doesn't mean what you seem to think it does.

  4. #4
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Question about classes in VB6

    Quote Originally Posted by Elroy View Post
    Hi Ben,

    I'm sure Olaf will chime in on this one, as he's quite the expert on COM, COM+, and class instantiation. However, it's my understanding that a single copy of the code is loaded on the first instantiation. Since the code is re-entrant, you'll only need one copy. However, all variables, including module level and statics, will have separate copies created.

    Hope That Helps,
    Elroy
    I don't pretend to know a lot about how the internals of a class work, but while developing SimpleServer, I discovered that variables appear to be common to all instances of a class (it uses a class array). For further information, see:

    http://www.vbforums.com/showthread.p...ht=stress+test

    J.A. Coutts

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

    Re: Question about classes in VB6

    Quote Originally Posted by Ben321 View Post
    When you set an object variable to a class, it creates an instance of that class. That instance includes a a VTable with pointers to functions, and also a copy of any variables the class uses. What I'm not sure of is this. Does the class instance also contain a copy of the executable code that was initially stored in the base class? Or do the entries in the VTable in every instance always point to code in the base class?

    I'm sensing a deeper question here. You are concerned with VTables for some reason.

    An object variable is actually a pointer to the object. When you instantiate an object, you can have multiple variables referencing that same object. When assign an object variable the value of another object variable, it only copies the reference to that object, hence both variables will point to the same object. That means if you change a property of an object using one variable, it will be reflected when you read that same property using another variable.
    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,940

    Re: Question about classes in VB6

    Sighs at dilettante's reply. Ben, I was assuming (and, I think correctly so) that you know the difference between just declaring a variable for an object/class, instantiating that variable with the New keyword, and using it as an alias of an already instantiated class. As these are all three separate things, although often combined.

    Also, to be completely technically accurate, when using the New keyword with the declaration, the class isn't instantiated until its first "touched" for use. I'm actually not sure if this is true when New is done separately from the declaration. For instance:

    Code:
    
        Dim o As SomeClass
        Set o = New SomeClass   ' Is instantiation done here ?
        o.SomeProperty = 5      ' Or is it done here ?
    
    Yes, use of the VTable of an instantiated class is a more involved question, but clearly still an interesting one. It involves some "tricky" use of the AddressOf operator, and you must also be very careful because there's no checking of whether you're passing your arguments correctly when jumping into a class's methods that way.

    Good Luck,
    Elroy
    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
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,538

    Re: Question about classes in VB6

    @Elroy - if the New keyword is done on the declaration line, correct, the actual instanciation isn't done until the first time it's touched. If the New keyword is used on a Set line the instance is created then.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

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

    Re: Question about classes in VB6

    Thanks tg. Good to know.
    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
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Question about classes in VB6

    Quote Originally Posted by Ben321 View Post
    Does the class instance also contain a copy of the executable code that was initially stored in the base class? Or do the entries in the VTable in every instance always point to code in the base class?
    code is stored in a a code segment which is part of an executable or library. So your classes code is "loaded" into memory as soon as the exe or library is loaded. Your Class Factory (when using new) just points the VTable to the actual code sitting in the loaded memory.



    (not to confuse the issue, but transparently windows uses a virtual memory manager that can delay physically loading portions of a library or exe into RAM until they are accessed.)

    https://en.wikipedia.org/wiki/Code_segment
    https://en.wikipedia.org/wiki/Loader_(computing)

    now that you understand the primary function of what an executable loader does (pertaining to all languages and Operating Systems), do you want to re-word the question?
    Last edited by DEXWERX; Jan 17th, 2018 at 08:33 AM.

  10. #10
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,163

    Re: Question about classes in VB6

    The VTable is compiled along with the code (in different section) and it‘s never modified or constructed at run-time once loaded. When an instance of a class is created its memory block first 4 bytes get initialized to point to this static class VTable, while ObjPtr points to the instance memory block. To call a function from ObjPtr deref VTable and get pfn from certain offset in VTable then pass ObjPtr as first param to this function.

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

    Re: Question about classes in VB6

    Alright, and hopefully I'm not hijacking this thread ... but I've got a related question regarding some things that were just mentioned. I've never had this clear, and wouldn't mind a clear explanation.

    Back in the DOS days, we learned to make extensive use of overlays (linking our OBJ files in various ways so that only portions of them would be loaded into memory, via use of parentheses in the linker commands). This was absolutely necessary to get things to fit into memory (which was clearly MUCH more limited than it is now).

    I know there are inaccuracies in this statement, but I've always roughly assumed that classes were much like these DOS overlays. I suppose, to formulate a question, it would be in response to this comment...

    Quote Originally Posted by DEXWERX View Post
    code is stored in a a code segment which is part of an executable or library. So your classes code is "loaded" into memory as soon as the exe or library is loaded.
    Now, I "heard" the following comment about Windows managing memory. However, here's my question: Is this to say all the compiled code of a VB6 project (as well as all loaded ActiveX projects) must simultaneously fit into a 4GB (actually 2GB) address space?

    In other words, I always assumed that, upon instantiation, a class's code was pulled into memory with all its relocatable-address-pointers patched up at that point. In that way, an overall project (including ActiveX components) may far exceed the 4GB (or 2GB) limit, so long as the "loaded" code didn't exceed those limits.

    Any clarification on this point would be much appreciated. Also, I'm not nearly as concerned about how paging and Windows memory management fits into this (which I see as at a lower level than my question).

    Best Regards,
    Elroy

    EDIT1: And what I hear wqweto saying is: All VTables are loaded into memory upon project execution. However, they may be "patched up" upon the first instantiation of a class. That actually makes more sense to me. It'd be interesting to know whether or not a VTable has been initialized. Maybe the first 12 bytes are zero if it hasn't.
    Last edited by Elroy; Jan 17th, 2018 at 09:43 AM.
    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
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Question about classes in VB6

    Quote Originally Posted by wqweto View Post
    The VTable is compiled along with the code (in different section) and it‘s never modified or constructed at run-time once loaded. When an instance of a class is created its memory block first 4 bytes get initialized to point to this static class VTable, while ObjPtr points to the instance memory block. To call a function from ObjPtr deref VTable and get pfn from certain offset in VTable then pass ObjPtr as first param to this function.
    I think with VC++ (and VB) it's in a read only data section.
    That's why VirtualProtect is used to get Write Access to the memory before attempting to change any function pointers.

    (just adding supporting info!)
    Last edited by DEXWERX; Jan 17th, 2018 at 09:40 AM.

  13. #13
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Question about classes in VB6

    Quote Originally Posted by Elroy View Post
    Is this to say all the compiled code of a VB6 project (as well as all loaded (IN PROCESS) ActiveX projects) must simultaneously fit into a 4GB (actually 2GB) address space?
    in short... Yes

    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    maybe you're thinking of working sets? https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    NOTE:compiled code is pretty small compared to uncompiled code.

    @Elroy: do your programs and DLLs take up more than 4G on disk?
    Last edited by DEXWERX; Jan 17th, 2018 at 10:10 AM.

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

    Re: Question about classes in VB6

    @Dex: That's actually a good question. And, you're right. They're nowhere close. Here's a "shot" of my dependencies:

    Name:  dep.jpg
Views: 554
Size:  27.6 KB

    My executable isn't quite so forward, as I've got all kinds of stuff crammed into the resources. However, I guess I could just subtract the two.

    .RES is 171,549 KB.
    .EXE is 188,336 KB.

    So that suggests something in the neighborhood of 16,787 KB of code.

    Adding them all together, that's 82,281 KB, or, say 82 MB, nowhere close to 2 GB. Hmmm, so I guess I've got nothing to worry about.

    Thanks for pointing that out.

    Elroy

    EDIT1: And yeah, I know that other in-process dependencies are pulled in, but still, it looks like I'm nowhere close to any limits.

    EDIT2: Also, things like that Help_MfmAng.dll file are chocked full of pictures, scattered throughout many forms. I'm thinking that they're not loaded unless the form is loaded. The code (COM object) of a form may be loaded (even if not instantiated) but it wouldn't seem that the Windows' interface portion would be loaded, if not "Loaded" with the Load statement. (Although, that really is getting off-topic.)
    Last edited by Elroy; Jan 17th, 2018 at 12:03 PM.
    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.

  15. #15
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,163

    Re: Question about classes in VB6

    Quote Originally Posted by Elroy View Post
    All VTables are loaded into memory upon project execution. However, they may be "patched up" upon the first instantiation of a class. That actually makes more sense to me. It'd be interesting to know whether or not a VTable has been initialized. Maybe the first 12 bytes are zero if it hasn't.
    You already mentioned about relocations. Imagine _Class1 (the interface) VTable as a static table with 15 addresses that get relocated on DLL load to point to the 15 functions in the DLL's code section. Now when an instance of Class1 is created there is this function (lets call it factory function) that first mallocs sizeof Class1 (i.e. a memory chunk that fits all member variables + some overhead) and set it's first 4 bytes to point to _Class1 VTable. So this Obj1 has no copy of the VTable only a single 4-byte pointer to the static _Class1 VTable, the one the PE loader did 15 relocations to in the beginning.

    So you can get the address of this table, make it writable w/ VirtualPotect and patch a certain function to point to a function in a BAS module of yours. The thing is that when you create a new instance of Class1 (e.g. Obj2) its certain function automagically will be pointing to your BAS module too because all instances of Class1 share this common already patched _Class1 VTable.

    So what some people do is get the address of the VTable, copy the whole of it to a member byte array and modify Obj2 first 4-bytes (the so called VTable *pointer*) to reference this new byte array, then modify a single function in this new VTable to point to a function in a BAS module of theirs. This allows function hooking on object interfaces w/o disrupting existing or new instances of Class1.

    But still, not making a separate copy allowed LaVolpe to patch StdPicture default interface for instance, so all StdPictures started loading/displaying animated GIFs -- pure magic :-))

    cheers,
    </wqw>

  16. #16
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Question about classes in VB6

    Great Info. I think wqweto managed to give enough detail to answer the OP too.

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

    Re: Question about classes in VB6

    Yes, wqweto, that's enlightening. Also, I wish Ben would make an appearance, as I truly don't want to completely hijack his thread. But I do find this quite interesting.

    I use classes all the time. And I've had a rough understanding of the VTable. But I'd love to have a stronger understanding (as well as VB6 code examples) of all of this.

    For instance, carrying this forward, hmmm ... let me just put together a code example, and then I'll speculate on what it's doing, with corrections welcomed. Also, let's set aside the discussions of replicating the VTable for other instances of an object, at least for now.

    For instance, here's some code:

    Code:
    
    Option Explicit
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Dest As Any, ByRef Source As Any, ByVal Bytes As Long)
    Private Declare Function VBObjPtr Lib "msvbvm60.dll" Alias "VarPtr" (ByVal pObj As IUnknown) As Long
    '
    
    Private Sub Form_Load()
        Dim c1 As Form1
        Dim c2 As Form1
        Set c1 = New Form1
        Set c2 = New Form1
    
        Debug.Print "----c1 ----"
        Debug.Print ObjPtr(c1); vbTab; "???"
        Debug.Print Ptr1(c1); vbTab; "c1 and c2 the same"
        Debug.Print Ptr2(c1); vbTab; "c1 and c2 the same"
        Debug.Print VarPtr(c1); vbTab; "Just pointing at the memory location of c1 variable."
        Debug.Print VBObjPtr(c1); vbTab; "???"
    
        Debug.Print "----c2 ----"
        Debug.Print ObjPtr(c2); vbTab; "???"
        Debug.Print Ptr1(c2); vbTab; "c1 and c2 the same"
        Debug.Print Ptr2(c2); vbTab; "c1 and c2 the same"
        Debug.Print VarPtr(c2); vbTab; "Just pointing at the memory location of c2 variable."
        Debug.Print VBObjPtr(c2); vbTab; "???"
    
        Debug.Print "---------"
    
        Unload Me
    End Sub
    
    Private Function Ptr1(o As Object) As Long
        CopyMemory Ptr1, ByVal ObjPtr(o), 4&
    End Function
    
    Private Function Ptr2(o As Object) As Long
        Dim p As Long
        CopyMemory p, ByVal ObjPtr(o), 4&
        CopyMemory Ptr2, ByVal p, 4&
    End Function
    
    To my eyes, ObjPtr(c1) is pointing at a specific instantiated instance of the object. It will be different for each instantiation.

    The Ptr1 is pointing at the VTable (I think), so, unless a VTable has been copied, it will be the same for all instances of a specific class.

    The Ptr2 is pointing at the QueryInterface code (I think).

    VarPtr(the object) is just pointing at the variable's memory address.

    And, VBObjPtr(the object), I've got no idea what this one is pointing at.


    If someone would specify all this stuff, that'd be absolutely great.

    Elroy
    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.

  18. #18
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Question about classes in VB6

    Name:  ObjLayout.jpg
Views: 530
Size:  23.0 KB
    Last edited by DEXWERX; Jan 17th, 2018 at 03:22 PM.

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

    Re: Question about classes in VB6

    The VBObjPtr() is a different value when called against a regular class as well (say, Class1).

    And, FYI, that's an excellent explanation.
    Last edited by Elroy; Jan 17th, 2018 at 03:23 PM.
    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.

  20. #20
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Question about classes in VB6

    Quote Originally Posted by Elroy View Post
    The VBObjPtr() is a different value when called against a regular class as well (say, Class1).
    check your declaration of VBObjPtr(). it's querying for IUnknown. Change it to Form1/Class1 and be amazed.


    FYI: your VBObjPtr() function is casting/QI'ing to IUnknown, which is a totally different interface vs Form1.
    You need to understand interfaces and Basic COM to get why that makes a difference. But basically it's a different interface to the same object.
    Different Interface usually means different VTable and different instance data.

    Code:
    Option Explicit
    
    Private Declare Function GetMem4 Lib "msvbvm60" (Src As Any, Dst As Any) As Long
    Private Declare Function VBObjPtr Lib "msvbvm60.dll" Alias "VarPtr" (ByVal pObj As IUnknown) As Long
    
    Private Property Get DeRef(ByVal Address As Long) As Long
        GetMem4 ByVal Address, DeRef
    End Property
    Private Property Let DeRef(ByVal Address As Long, ByVal Value As Long)
        GetMem4 Value, ByVal Address
    End Property
    
    Private Sub Form_Load()
        Dim c1 As Form1
        Dim c2 As Form1
        Set c1 = New Form1
        Set c2 = New Form1
    
        Debug.Print "----c1 ----"
        Debug.Print VarPtr(c1), "Address Variable"
        Debug.Print VBObjPtr(c1), "Address of Instance Data for IUnknown"
        Debug.Print DeRef(VBObjPtr(c1)), "Address of VTable for IUnknown"
        Debug.Print DeRef(DeRef(VBObjPtr(c1))), "Address of QueryInterface Code for IUnknown"
        
        Debug.Print ObjPtr(c1), "Address of Instance Data for Form1"
        Debug.Print DeRef(ObjPtr(c1)), "Address of Vtable for Form1"
        Debug.Print DeRef(DeRef(ObjPtr(c1))), "Address of QueryInterface Code for Form1"
        
        Debug.Print "----c2 ----"
        Debug.Print VarPtr(c2), "Address Variable"
        Debug.Print VBObjPtr(c2), "Address of Instance Data for IUnknown"
        Debug.Print DeRef(VBObjPtr(c2)), "Address of VTable for IUnknown"
        Debug.Print DeRef(DeRef(VBObjPtr(c2))), "Address of QueryInterface Code for IUnknown"
        
        Debug.Print ObjPtr(c2), "Address of Instance Data for Form1"
        Debug.Print DeRef(ObjPtr(c2)), "Address of Vtable for Form1"
        Debug.Print DeRef(DeRef(ObjPtr(c2))), "Address of QueryInterface Code for Form1"
    
        Unload Me
    End Sub

  21. #21
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,066

    Re: Question about classes in VB6

    Quote Originally Posted by couttsj View Post
    variables appear to be common to all instances of a class
    That's wrong. Check the test program that is attached.
    Attached Files Attached Files

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

    Re: Question about classes in VB6

    @couttsj & Eduardo: Variables are common to all Aliases of a class, but they're not at all common to all Instances of a class. Those two concepts are entirely different. Couttsj, I suspect you were aliasing your class rather than creating different instances when you were doing your testing.

    EDIT1:
    Code:
    
    Private Sub AnInstantiationAndAnAlias()
        Dim c1 As Class1
        Dim c2 As Class1
    
        Set c1 = New Class1     ' <--- Instantiation.
        Set c2 = c1             ' <--- Creates an alias.
    End Sub
    
    Private Sub TwoInstantiations()
        Dim c1 As Class1
        Dim c2 As Class1
    
        Set c1 = New Class1     ' <--- Instantiation.
        Set c2 = New Class1     ' <--- Instantiates another instance.
    End Sub
    
    
    Last edited by Elroy; Jan 17th, 2018 at 04:29 PM.
    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.

  23. #23
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Question about classes in VB6

    Quote Originally Posted by Elroy View Post
    @couttsj & Eduardo: Variables are common to all Aliases of a class, but they're not at all common to all Instances of a class. Those two concepts are entirely different. Couttsj, I suspect you were aliasing your class rather than creating different instances when you were doing your testing.
    Sorry, but I don't understand the concept of aliasing. Is this aliasing?
    Code:
        ReDim mServer(MaxClients)
        For lNum = 0 To MaxClients
            Set mServer(lNum).Callback(lNum) = Me
            mServer(lNum).IPvFlg = 4
        Next
    And if so, how would it be done differently?

    J.A. Coutts

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

    Re: Question about classes in VB6

    Hi couttsj,

    From the bit you've given us, I'm not sure what you're trying to do. However, this is one way you could instantiate a different class for each mServer in the array. All you've done is to create an array of aliases, all of the same object's instantiation.

    A slightly different version of your code might look something like:

    Code:
    
        Const MaxClients = 5
        Dim lNum As Long
        Dim mServer() As SomeClass
        ReDim mServer(MaxClients - 1)
    
    
        For lNum = 0 To MaxClients - 1
            Set mServer(lNum) = New SomeClass
        Next
    
    In that example, I've got five separate instantiations (with five possible sets of variables within SomeClass).



    The secret is all in the New keyword.

    EDIT1:

    It's not terribly easy (and sometimes dangerous) to alias regular variables in VB6, but here's an example (and a safe one too):

    Code:
    
    Option Explicit
    
    Dim mlValue As Long
    
    
    Private Sub Form_Load()
    
        mlValue = 5
        Test mlValue
    
    End Sub
    
    Private Sub Test(l As Long)
    
        MsgBox CStr(l) & "   " & CStr(mlValue)
    
            l = 6
    
        MsgBox CStr(l) & "   " & CStr(mlValue)
    
            mlValue = 7
    
        MsgBox CStr(l) & "   " & CStr(mlValue)
    
    End Sub
    
    
    Last edited by Elroy; Jan 17th, 2018 at 05:50 PM.
    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.

  25. #25
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Question about classes in VB6

    Quote Originally Posted by couttsj View Post
    Sorry, but I don't understand the concept of aliasing. Is this aliasing?
    Yes

    Quote Originally Posted by couttsj View Post
    And if so, how would it be done differently?
    Code:
        ReDim mServer(MaxClients)
        For lNum = 0 To MaxClients
            Set mServer(lNum).Callback(lNum) = New Class1 ' New Instance with separate local variables.
            mServer(lNum).IPvFlg = 4
        Next

  26. #26
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,255

    Re: Question about classes in VB6

    Quote Originally Posted by couttsj View Post
    Sorry, but I don't understand the concept of aliasing. Is this aliasing?
    Code:
        ReDim mServer(MaxClients)
        For lNum = 0 To MaxClients
            Set mServer(lNum).Callback(lNum) = Me
            mServer(lNum).IPvFlg = 4
        Next
    The above would only work, in case you have defined the mServer()-Array with the New-keyword.
    If that is the case, then no - this is not "aliasing" (which is just another word for: "two different Variables point to the same thing").

    What I find surprising is, that not many devs have done a few tests themselves (a decade or two ago),
    by using a simple Class1 - and a few Debug-Statements in its Class-Init and Terminate-Events.

    Because doing so would shed a lot of light on "when things start to come online" and "when things are going to die"...

    Here's some code, which shows what's going on behind the scenes of your example:

    Class1:
    Code:
    Option Explicit
    
    Private Sub Class_Initialize()
      Debug.Print "Class1 instantiated: " & ObjPtr(Me)
    End Sub
    
    Public Property Get SomeProp() As String
      SomeProp = "Class1 PropAccess: " & ObjPtr(Me)
    End Property
    
    Private Sub Class_Terminate()
      Debug.Print "Class1 terminated: " & ObjPtr(Me)
    End Sub
    Form-Code:
    Code:
    Option Explicit
    
    Private mServer() As New Class1, lNum As Long
    
    Private Sub Form_Click()
        ReDim mServer(2) 'a Redim like that (without Preserve) destroys any potentially existing intances in the Array
        For lNum = 0 To UBound(mServer)
          Debug.Print mServer(lNum).SomeProp
        Next
    End Sub
    Please click repeatedly on the Form - whilst having a breakpoint at the first statement in Form_Click.
    Then step through it and watch the Debug-Window (there's only 3 entries in the Array, won't take long).

    HTH

    Olaf

  27. #27
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,066

    Re: Question about classes in VB6

    couttsj: one thing are object instances and another thing are object references that are hold in variables.

    A new object (Class) instance is created with the keyword New.

    Code:
        Dim c as Class1
    
        Set c = New Class1
    This code creates one instance of Class1 object and set a reference to it in the variable c.

    Code:
        Dim c as Class1
        Dim c2 as Class1
    
        Set c = New Class1
        Set 2 = New Class1
    This code creates two instances of Class1 and set a refrence of the first one to the variable c and a reference of the second one to the variable c2.

    Code:
        Dim c as Class1
        Dim c2 as Class1
    
        Set c = New Class1
        Set 2 = c
    This code creates only one instance of Class1 and set a reference to it to the variable c and another reference to this very same object instance to the variable c2.

  28. #28
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,066

    Re: Question about classes in VB6

    The keyword Me returns a reference to the object where it is invoked.

    It can be a Form, a Class or some other object that have a code module like an UserControl.

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

    Re: Question about classes in VB6

    Quote Originally Posted by Eduardo- View Post
    The keyword Me returns a reference to the object where it is invoked.

    It can be a Form, a Class or some other object that have a code module like an UserControl.
    Yes, or said differently, Me is a pre-declared, scoped within the object's COM/code module, alias of the object.
    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.

  30. #30
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Question about classes in VB6

    I think I may have led your guys astray. I did not show you how the array was created.
    Code:
    Implements SimpleServer
    Private mServer() As New SimpleServer
        ReDim mServer(MaxClients)
        For lNum = 0 To MaxClients
            Set mServer(lNum).Callback(lNum) = Me
            mServer(lNum).IPvFlg = 4
        Next
    The problem was not in the class. The SimpleServer class was able to handle the various data arrays and keep them separate. The problem was actually in the callback routine in the form. It was not able to keep the receive buffers separate, so I changed the code to accumulate the data in the class instead.

    J.A. Coutts

  31. #31
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,066

    Re: Question about classes in VB6

    Quote Originally Posted by Elroy View Post
    Yes, or said differently, Me is a pre-declared, scoped within the object's COM/code module, alias of the object.
    I call them references, not aliases.
    I don't know if both terms are correct or only one.

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

    Re: Question about classes in VB6

    @Eduardo: IMHO, either/both terms would be correct. I must admit that I learned about aliasing with respect to more typical variables. To me, it's just when you have two named references (like a variable's name) that refer to the same data and are both being used within the same (or similar scope).

    However, I suppose the way COM objects keep track of things with an internal counter, the word "references" may be a bit more appropriate. It'd be hard for me to break the habit of calling them aliases though.

    Take Care,
    Elroy

    EDIT1: Ohhh, I just Googled around a bit, and apparently, some call them "alias references".
    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.

  33. #33
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,066

    Re: Question about classes in VB6

    Quote Originally Posted by couttsj View Post
    I think I may have led your guys astray. I did not show you how the array was created.
    Code:
    Implements SimpleServer
    Private mServer() As New SimpleServer
        ReDim mServer(MaxClients)
        For lNum = 0 To MaxClients
            Set mServer(lNum).Callback(lNum) = Me
            mServer(lNum).IPvFlg = 4
        Next
    The problem was not in the class. The SimpleServer class was able to handle the various data arrays and keep them separate. The problem was actually in the callback routine in the form. It was not able to keep the receive buffers separate, so I changed the code to accumulate the data in the class instead.

    J.A. Coutts
    I'll post in your thread.

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