Understanding Delphi’s perception of COM

Delphi is great for COM if you want to do something simple; as soon as someting a little more complex is needed, COM in Delphi can be a real headache. Here is a braindump from a recent investigation:

The LocalServer class registration function CoRegisterClassObject is called for each Class Factory registered with the Singleton ComServer object in TComServer.Initialize. Class Factories are registered in the initialization section of units in which they are defined, and TComServer.Initialize does not get called until after Application.Initialize has been called (using some InitProc hackery in first ComObj and then ComServ). Crucially, ComServer is a helper object to guarantee registration of all the Class Factories in the application (or DLL), so ComServer.ObjectCount refers to the number of objects it has helped to create (via Class Factories) not the number of references held (say, externally) to any particular COM object.

A post from b.p.d.activex.controls.writing by one Patrice Corteel explains further:

Now let’s go a step further in COM threading model discussion and look at local and remote servers versus in-proc servers.
A Delphi local or remote exe server has a main thread which calls CoInitialize which makes it an apartment. And as a default behaviour, every COM component based on the delphi COM framework is created in this thread and marked as apartment threaded. If you explicitly spawn new threads you can initialize them as you want but you must get a marshalled interface to call components created by your main thread.
If you want to create free threaded components it’s far more difficult since you can’t rely directly on Delphi implementation and you have to rewrite large parts of ComServ and subclass many of ComObj classes. I’m currently working on this topic and I’ll post more on this when I am over with tests.

Note that if lengthy initialisation is needed, set ComServer.StartSuspended to True before Application.Initialize; this causes the class factories to be registered with the REGCLS_SUSPENDED flag, and ComServ.InitComServer makes the required call to CoResumeClassObjects to activate them again.



Join the discussion...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.