AddRef_Pointer typedef PROTO :DWORD Release_Pointer typedef PROTO :DWORD

 

In keeping with the MASM32 practice of "loose" type checking, function parameters are just defined as DWORDs. Lots of work to set things up, but it does keeps lots of errors confined to compile time, not run time. In practice, we will wrap up these interface definitions in include files and keep them from cluttering up the source code.

 

One rather big compilation on defining an interface: MASM cannot resolve forward references like this, so we have to define them backwards, by defining the function prototype typedefs first, and the interface table last. The include files for the example program later on defines the interfaces this way.

 

To actually use an interface, you need a pointer to it.

 

The CoCreateInstance API can be used to return us this indirect pointer to an interface structure. It is one level removed from the vtable itself, and actually points to the "object" that holds the interface. The final structure looks like this:

 
 

 

There is a lot of indirection using this structure, it can drive you batty trying to write code to properly reference and de-reference these elements. Macros to simplify this task will be defined.

 

When the client makes a call to the COM library to create a COM object, it passes in the address where it wants the object pointer to be placed. This initial pointer is generically referred to as "ppv," from the C++ speak "pointer to pointer to (void)," where (void) means an unspecified type. It holds the address of another pointer ("pv"), and this pointer refers to a whole table of pointers, one table entry for each function of the interface.

 

For example, say we used CoCreateInstance and successfully got an interface pointer ppv, and wanted to see if it supports some other interface. We can call its QueryInterface method and request a new ppv (ppv2, pointer to an Interface) to the other interface (pIID, pointer to a Interface Identifying GUID) we are interested in. In C, QueryInterface has a prototype that would look like so:

 

(HRESULT) SomeObject::QueryInterface (this:pObject, IID:pGUID, ppv2:pInterface)

 

 

Such a call would look like this:


; get pointer to the object
mov eax, ppv