In some of POCO libraries (Net on Windows, Data back-ends, Crypto, NetSSL …), there is a need for early library initialization. This task has been done so far in a couple of ways (neither elegant) – we either
- (1) call initialization (repeatedly) from some strategic points in the library (Net, SSL) that we know will get hit early, or
- (2) mandate early explicit call (un)initialization (Data back-ends) early from user code.
So, the question here is: can we (and, if the answer is yes, how?) improve the current state?
- Problem: do tasks early at application init or shared library load, ensuring they are executed prior to any other activity depending on them.
- Examples: Windows network initialization, DB back-end registration with front-end registry …
- Solution: looks simple at first, then not so simple when the reality of (1) dynamic/static linkage (on Windows in particular), (2) static variable initialization timing/order and (3) dynamic library loading order (e.g. Data and back-end libraries) hits.
At first, one would think this (SQLite back-end with abbreviated names used as an example here) will do the trick:
struct SQLite_API SQLiteRegistrator
extern "C" struct SQLite_API SQLiteRegistrator sqliteRegistrator;
Alas, MSVC will disregard your wishes in both static and dynamic library builds when it sees that the registrator is “not used” anywhere. Luckily, there’s a way to force the linkage:
#pragma(comment (linker, "/include:_sqliteRegistrator")
With some ifdef-ing for 64-bit (no underscore decoration) and dynamic exports, it turns out that the task is achievable:
#pragma(comment (linker, "/export:sqliteRegistrator")
So, now we have a way to force initialization without having to explicitly call registerConnector from user code (or peppering library with initialization code).
Details are in GitHub repo (Net and Data back-ends only at the time of this writing).
This modification was tested on Windows, Mac and Linux, static and shared builds; I’m putting a word out to hear comments and make sure I did not miss something important, so suggestions are more than welcome. I’d like to have this in the upcoming 1.5.2.