|
-
Aug 19th, 2016, 11:13 AM
#1
[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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|