Results 1 to 40 of 60

Thread: [RESOLVED] Digging into COM from Class1 inside a standard VB6 EXE project.

Threaded View

  1. #1

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Resolved [RESOLVED] Digging into COM from Class1 inside a standard VB6 EXE project.

    I'd like to learn a bit more about getting into the guts of instantiated COM objects.

    I know there are a few people here fairly on top of this. LaVolpe, Bonnie, Olaf, fafalone, TheTrick, and others certainly come to mind. And, of course, the illustrious Dexwerx, dilettante, and wqewto. Sorry if I've snubbed you in that list.

    In the past, most of it distant, I've done assembler, C, Fortran, and even a bit of PLI programming. However, none of that directly dealt with COM object instantiation. In fact, most of it was before COM objects were used. Some of the Fortran actually did utilize COM objects, but not in a "getting into guts" way.

    For years, in VB6, I've played around a bit with these COM object, messing around with the DispCallFunc API call; exploring what tlbinf32.dll can do for us; trying to get the ideas of how IUnknown, QueryInterface, AddRef, Remove work; understanding the idea of a vtable and a TypeLib; and how all that connects to the address returned by ObjPtr. But my knowledge is clearly not be-all-end-all with respect to these things.

    I'd like to learn more, but the way I learn best is to have a specific task to tackle.

    Therefore, here's my task: Let's forget external libraries, and stay strictly within a VB6 Standard EXE project. As we all know, we can create classes within these projects (and forms as well, which are just classes with a windows interface). And then, we can use object variables to instantiate these classes for use in our code (possibly even using the VB_PredeclaredId flag to auto-instantiate them).

    So, within that circumscribed realm, here's what I'd like to do. I'd like to create a class (let's call it Class1 for simplicity). Then, I'd like to add some Public methods and properties to it. (Let's defer any discussion of "Friend" until another time.)

    And then, I'll instantiate an object variable with this class. So, let's say we have the following:

    Class1 code:
    Code:
    
    Option Explicit
    
    Public testprop1 As String
    '
    Dim m_testprop2 As String
    '
    
    Public Property Let testprop2(s As String)
        m_testprop2 = s
    End Property
    
    Public Property Get testprop2() As String
        testprop2 = m_testprop2
    End Property
    
    Public Sub testsub(s As String)
        Dim i As Long
        i = i + 1
        ' just a nonsense test. 
    End Sub
    
    Public Function testfunction() As Long
        testfunction = Rnd * 10000
        ' another nonsense test. 
    End Function
    
    And, in our Form1 that we're just using for testing, we've got:
    Code:
    
    Option Explicit
    
    Private Sub Form_Load()
        Dim c As Class1     ' Create object variable restricted to being instantiated with Class1. 
    
        Set c = New Class1  ' Instantiate Class1. 
    
    
    
        Stop
        Unload Me
    End Sub
    
    Okay, here's my objective: I'd like to enumerate all the exposed (Public) methods and properties of my instantiated Class1 (in my c variable), and I'd like to do this both while running p-code in the IDE and while running machine code in a compiled program. I've managed to do it in the IDE using tlbinf32.dll. However, that same approach fails when you compile the program and run the executable.

    At first, one might think that the necessary data isn't inside the executable. However, if that were true, how could something like the following work:

    Code:
    
    Option Explicit
    
    Private Sub Form_Load()
        Dim c As Class1     ' Create object variable restricted to being instantiated with Class1. 
    
        Set c = New Class1  ' Instantiate Class1. 
    
        CallByName c, "testprop1", VbLet, 1234
        MsgBox c.testprop1 ' <--- clearly, CallByName found the "testprop1" property, as this reports 1234. 
    
    
        ' OR 
    
    
        MsgBox CallByName(c, "testfunction", VbMethod) ' <--- successfully reports some random number. 
        ' Again, the CallByName successfully finds the method. 
    
        ' So, why can't we just enumerate them? !!! 
        ' Obviously, CallByName can find the internal TypeLib table, so why can't we? 
    
        Stop
        Unload Me
    End Sub
    
    Apparently, there's something like an internal TypeLib for each of our class (and form) modules in the executable. I think what I'm wanting to do is "get at" that TypeLib. I've explored the vtable with ObjPtr, but that doesn't get me anywhere. There are only pointers to the methods and properties in the vtable, no names.

    It just seems like this should be possible. Any ideas?
    Last edited by Elroy; Aug 19th, 2016 at 12:12 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.

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