Tricks of the Windows Game Programming Gurus:DirectX Fundamentals and the Dreaded COM

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

#### Building a Quasi-COM Object

Creating a full-fledged COM object is well beyond the scope of this book. You only need to know how to use them. However, if you’re like me, you like to have some idea of what’s going on. So what we’re going to do is build up a very basic COM example to help you answer some of the questions that I’m sure I’ve created for you.

All right, you know that all COM objects contain a number of interfaces, but all COM objects must be derived from the `IUnknown` class to begin with. Then, once you have all your interfaces built, you put them all in a container class and implement everything. As an example, let’s create a COM object that has three interfaces: `ISound`, `IGraphics`, and `IInput`. Here’s how you might define them:

    // the graphics interface

    struct IGraphics : IUnknown

    {

    virtual int InitGraphics(int mode)=0;

    virtual int SetPixel(int x, int y, int c)=0;

    // more methods...

    };

    // the sound interface

    struct ISound : IUnknown

    {

    virtual int InitSound(int driver)=0;

    virtual int PlaySound(int note, int vol)=0;

    // more methods...

    };

    // the input interface

    struct IInput: IUnknown

    {

    virtual int InitInput(int device)=0;

    virtual int ReadStick(int stick)=0;

    // more methods...

    };

Now that you have all your interfaces, let’s create your container class, which is really the heart of the COM object:

    class CT3D_Engine: public IGraphics, ISound, IInput

    {

    public:

    // implement IUnknown here

    virtual HRESULT __stdcall QueryInterface(const IId& iid,

                                            (void **)ip)

    { /* real implementation */ }

    // this method increases the interfaces reference count

    virtual ULONG __stdcall Addref()

                            { /* real implementation */}

    // this method decreases the interfaces reference count

    virtual ULONG __stdcall Release()

                            { /* real implementation */}

    // note there still isn’t a method to create one of these

    // objects...

    // implement each interface now

    // IGraphics

    virtual int InitGraphics(int mode)

                         { /*implementation */}

    virtual int SetPixel(int x, int y, int c)

                         {/*implementation */}

    // ISound

    virtual int InitSound(int driver)

                         { /*implementation */}

    virtual int PlaySound(int note, int vol)

                         { /*implementation */}

    // IInput

    virtual int InitInput(int device)

                         { /*implementation */}

    virtual int ReadStick(int stick)

                         { /*implementation */}

    private:

    // .. locals

    };

> Note: You’re still missing a generic way to create a COM object. This is a problem, no doubt. The COM specification states that there are a number of ways to do it, but none of them can tie the implementation to a specific platform or language. One of the simpler ways to do it is to create a function called `CoCreateInstance()` or `ComCreate()` to create the initial `IUnknown` instance of the object. The function usually loads a DLL that contains the COM code and works from there. Again, this technology is beyond what you need to know, but I just want to throw it out there for you. However, we’re going to cheat a little to continue with the example.

As you can see from the example, COM interfaces and coding are nothing really more than slightly advanced C++ virtual classes with some conventions. However, true COM objects must be created properly and registered in the registry, and a number of other rules must be adhered to. But at the lowest level, they are simply classes with methods (or for you C programmers, structs) with function pointers, more or less. Anyway, let’s take a brief step back and review what you know about COM.

#### A Quick Recap of COM

COM is a new way of writing component software that allows you to create reusable software modules that are dynamically linked at run-time. Each of these COM objects has one or more interfaces that do the actual work. These interfaces are nothing more than collections of methods or functions that are referenced through a virtual function table pointer (more on this in next section).

Each COM object and interface is unique from the others due to the use of GUIDs, or Globally Unique Identifiers, that you must generate for your COM objects and interfaces. You use the GUIDs or IIDs to refer to COM objects and interfaces and share them with other programmers.

If you create a new COM object that upgrades an old one, you must still implement the old interfaces along with any new ones you might add. This is a very important rule: all programs based on COM objects should still work, without recompilation, with new versions of the COM object(s).

COM is a general specification that can be followed with any language on any machine. The only rule is that the binary image of the COM object must be that of a virtual class generated by a Microsoft VC compiler—it just worked out that way. However, COM can be used on other machines, like Mac, SGI, and so on, as long as they follow the rules for using and creating COM objects.

Finally, COM opens up the possibility of creating massive computer programs (in the multibillion-line range) by means of its component-level generic architecture. And of course, DirectX, OLE, and ActiveX are all based on COM, so you need to understand it!

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.