Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with COM (un)initialization from a library perspective?

Tags:

com

delphi

From reading several answers on this site, I learned that CoInitialize(Ex) should be called by the creator of a thread. Then, any code running in that thread can use COM. If that code happens to call CoInitialize(Ex) by itself, that would be harmless, because it would have no effect. It should not call CoUninitialize – that too should be done by the creator of the thread – but it won't if it inspects the (saved) result of CoInitialize(Ex) which would be S_FALSE. If the creator would not take responsibility for performing the initialization, the thread is at the "mercy" of that code to pick an appropriate threading model, which from then on won't be changeable.

What are the implications of all this for writing and using libraries?

When all code is your own, and you have a small team, it is manageable to organize the COM (un)initialization calls well. However, with libraries, the user shouldn't need to know how they do what they do, e.g. that COM is involved. I'd hate to have in documentation what can be dealt with in code. Also, no assumptions should be made about what thread the library's code will run in, unless it concerns VCL code.

Most open source libraries I've inspected call CoInitialize(Ex) in the initialization section and CoUninitialize in the finalization section, often even without checking if initialization succeeded. Some call InitProc instead, yet some first check IsLibrary.

What is it that they really should be doing? What if I'd write a unit myself that I'd want anyone to be able to use without much consideration? Wrap everything that touches COM in a thread and have that thread perform its own COM (un)initialization?

How bad is it really to be naive about it, like those open source units? When using them in a VCL app, their COM (un)initialization would always run on the main thread, which already has that performed first by Forms.TApplication.Create. Does that make the calls in the units innocent but useless? What if any of the units is listed in the .dpr before Forms? What about non-VCL apps, or DLL's? Should I not use such units before having them corrected? Should I somehow guard against what they might try to do, by preventively initializing COM always?

This is a rather complex question, but it all boils down to: how to (make it easy to) avoid trouble with regards to COM (un)initialization?

like image 459
Thijs van Dien Avatar asked Mar 11 '23 05:03

Thijs van Dien


1 Answers

It's simple enough. Document that any consumers of your library must initialize COM. It's perfectly respectable and commonplace to do that. There's really nothing to worry about in placing such a requirement on the consumers of your library. If they fail to do what is required of them, that is their problem. As you point out, the creator of the thread has to take charge of initializing COM so you have no viable alternative.

like image 106
David Heffernan Avatar answered Apr 09 '23 23:04

David Heffernan