1. Technology
An Introduction to COM Programming with Delphi (4 / 6)
Page 1: A Com Object walk-a-bout. A Class Factory tour.
 More of this Feature
• Page 2: Our first true COM Object program
• Page 3: Homework Assignment
 More Delphi COM Lessons
• TOC
• Lesson 1
• Lesson 2
• Lesson 3
• Lesson 5
• Lesson 6
 Join the Discussion
"Post your views, comments, questions and doubts to this article."
Discuss!
 Related Resources
• COM / OLE / ActiveX programming with Delphi

Article written by Curtis Socha, brought to you by Zarko Gajic.

A Com Object walk-a-bout

A Com Object can exist within your own program, but as a rule, a Com Object usually resides in a DLL. Also, Com Objects require that the language that is calling it use an interface with a GUID. This means that only Microsoft C++, and Borland C++/Delphi will be able to use a Com Object unless you use automation.

One of the cool things about Com Objects is that have the ability to register themselves, literally, into the Windows registry. This means that if a program needs to use your Com Object, the registry knows where it is located and how to make the Com Object get created. Refer to the screen shot below to see what a registered Com Object looks like in the registry.

These particular GUID’s reside in your registry under HKEY_CLASSES_ROOT | CLSID. CLSID stands for Class Identification, which is essentially just a type of GUID. The registry also contains sub-categories for the CLSID. We will discuss these in a moment, but first, I would like to discuss the way you retrieve a Com object. There are essentially two ways to retrieve a Com Object. They are described as follows:

1) Com Objects that are retrieved from within a DLL are referred to as in-process servers.
2) Com Objects that are retrieved from within an executable are referred to as out-of-process servers.

Let us jump briefly back to the registry example. Notice the sub-key InProcServer32?

InProcServer32 means that the Com Object is retrieved from an in-process server, and as we can see in the default directory in the second window of the example, it is indeed a DLL that the CLSID is pointing to. Recall the fact that all GUID’s are unique. This means that only one CLSID for a specific Com Object will ever exist on any computer, and it will always point to the correct DLL. Isn’t that great news!

Com object in Registry

A Class Factory tour

Free COM Objects and Cokes will be provided during this tour...
Your application does not instantiate a Com Object directly. COM uses a class factory to instantiate a Com Object. The sole purpose of a class factory is to create other objects, (Ah, the joy of always serving others). There is a class factory associated with every Com Object and it is the class factory’s duty to instantiate the Com Object on the server.

In order to protect COM from the construction the Com Object itself, a class factory is used. Without class factories, COM would have to make a direct call to the constructor of the Com Object in order to create it.

Class factories provide implementation for the IClassFactory interface. Below is the code for IClassFactory as defined by The-Evil-Empire.

IClassFactory = interface(IUnknown)
  ['{00000001-0000-0000-C000-000000000046}']
  function CreateInstance(
                      const unkOuter: IUnknown; 
                      const iid : TIID; 
                      out obj) : HResult; stdcall;
  function LockServer(
               flock : BOOL) : HResult; stdcall;
end;

The job of the CreateInstance function is to create an instance of the Com Object that this Class Factory references. As I will explain in a little bit, COM will call this function for you. The LockServer function gives you the ability to keep a DLL registered, even if no active clients are using the server. Typically, the DLL will unload itself from memory if not active clients are using it. For every LockServer(True), there must be an equally placed LockServer(False), otherwise you end up with a DLL that never gets unloaded from memory. That would be bad.

In-Process COM Servers

In-Process COM Servers as you may recall are stored inside of a DLL. When the DLL is loaded, it will occupy the same address space as the application that called it. This is why it is called an In-Process Server. The DLL will literally become part of the application’s execution process.

I would like to take a moment to give you more information on how the DLL becomes registered/unregistered in the Windows registry, how it gets you your object, and how the DLL unloads itself from memory when finished. There four functions that In-Process COM Servers will export. They are listed below along with their descriptions:

  1. DllRegisterServer : This is called automatically by the Delphi’s Register ActiveX Server menu item or by using the command line RegSvr32.exe executable that comes with Windows. These two methods will call this function and register your COM Objects into the Windows Registry. How easy is that? It will then create the familiar sub-key InProcServer32 that we saw earlier in this lesson.
  2. DllUnRegisterServer: This exported function unregisters the server from the registry.
  3. DllGetClassObject: This function returns a class factory to COM so that it can create your specified COM Object.
  4. DllCanUnloadNow: COM calls this function to see if it can unload the server from memory. If there are no active clients, the server will be shut down. I think it is safe to assume that if you have LockServer set to True, it will not unload.

Threading support for In-Process COM Servers
At this time, we will not be discussing threading. For now, you will be using the Apartment threading model. Com Objects will only process requests from the thread that has created them. This means that a server can export multiple Com Objects, and that each Com Object may be created from a different thread. Even though these Com Objects may be running around on different threads, they can all still access global data that is defined within the server. In order to avoid thread collisions, you will want to use a critical section, semaphore, or mutex to protect the global data.

All of this hard earned knowledge will finally be put to use, by creating ...

Next page > Our first true COM Object program > Page 1, 2, 3

An Introduction to COM Programming with Delphi: Table of Content
<< Previous Lesson (3): What is the implements directive? What is the Method Resolution Clauses? Pseudo-Multiple Interface Inheritance. Interface properties and other fine tales of horror.
>> Next Lesson (5): Marshaling Data. Behold the power of Variant Arrays. Using Variants and Variant Arrays.

 

©2014 About.com. All rights reserved.