Increments or decrements the lock count

 

LockServer keeps the class factory instanced (helpful if one has to make numerous object copies). CreateInstance is the workhorse here, it is used to creates the object's "working" interface. Each class creates a class factory that solely knows how to create that particular class, since CreateInstance does not include a class reference ID. The class ID was specified when we created this class factory interface. Thus, a class factory only knows how to create interfaces of the class of which it is a member. It's sole purpose is to create the desired object class.

 

This indirection is useful if the class needs some special initiation. IClassFactory is necessary to handle aggregation (a topic I will have nothing more to add, and which the component made here does not support). Already, there is a definition for IClassFactory2, which checks licensing for the component.

 

To actually get your COM object, a client calls DllGetClassObject by invoking the CoCreateInstance API function. This API takes care of handling the class factory for you, and return the desired interface pointer. If you just need a plain vanilla object, this is the function to use. The CoGetClassObject API will return a pointer to IClassFactory is your class needs further creation parameters. Internally, CoCreateInstance itself calls CoGetClassObject and instance the class through IClassFactory, so you always need it define a class factory object creation interface.

 

 

Classes, Objects, you and THIS

---------------------------------------------------------------------------------------------------------------------I'm going to digress into some internal implementation details on how C++ handles objects. One can be a proficient C++ programmer and never fully understand this, as it is a level of complexity the compiler handles fully for you. However, the designers of COM took full advantage of the concept, and we need to understand this.

 

The new fundamental concept the ++ in C++ adds to the language is the concept of classes and objects. And object is an instance of a class. Let's explore what this means on a machine level. When we write a conventional program in asm, we depend on the compiler to create code and data segments for us. One area in memory is the code we execute, another holds the data we need. What the ++ in C++ does for you is dynamically reallocate data memory at run time, giving each instance of a class, each small segment of code it's own data segment. In a very real way, the instance of a class IS this data segment. Data specific to each instance (or copy) of the class is stored in this dynamic data area.

 

Perhaps you have heard that C++ passes an extra hidden parameter in function calls on an object, the THIS value. Whoever named this concept not only understood what was required, but had a good sense of humor. When one is writing low level code for an object (something the compiler usually does for you in C++), the first question one will have is "which object am I the code for?"

 

THIS is which object, one is always working with THIS object.

 

THIS is simply a pointer to the data memory area for THIS instance of the class. When an objects class function is called, THIS is silently passed on. When the private data of the object is accessed, the class code area uses THIS to reference where that data is for THIS instance.

 

Why is THIS important? Simply this: a pointer to a COM interface is same thing as the pointer to THIS. My Grammar checker is going nuts at me now, it may not be correct English but this is how THIS works.

 

In use, COM is simply a specification of interfaces. It says nothing about how they are actually implemented in code. In fact, it is written so such details are not defined such that any higher level language that implements these interfaces may be a COM server.

 

I defined my "class" data areas (the "objects") as thus: