{"id":741,"date":"2013-02-10T18:00:15","date_gmt":"2013-02-10T17:00:15","guid":{"rendered":"http:\/\/pocoproject.org\/blog\/?p=741"},"modified":"2013-02-10T18:44:14","modified_gmt":"2013-02-10T17:44:14","slug":"library-autoineatialization","status":"publish","type":"post","link":"https:\/\/pocoproject.org\/blog\/?p=741","title":{"rendered":"Library AutoiNEATialization"},"content":{"rendered":"<p>In some of POCO libraries (Net on Windows, Data back-ends, Crypto, NetSSL &#8230;), there is a need for early library initialization. This task has been done so far in a couple of ways (neither elegant) &#8211; we either<\/p>\n<ul>\n<li>(1) call initialization (repeatedly) from some strategic points in the library (Net, SSL) that we know will get hit early, or<\/li>\n<li>(2) mandate early explicit call (un)initialization (Data back-ends) early from user code.<\/li>\n<\/ul>\n<p>So, the question here is: can we (and, if the answer is yes, how?) improve the current state?<\/p>\n<ul>\n<li><strong>Problem:<\/strong> do tasks early at application init or shared library load, ensuring they are executed prior to any other activity depending on them.<\/li>\n<li><strong>Examples:<\/strong> Windows network initialization, DB back-end registration with front-end registry &#8230;<\/li>\n<li><strong>Solution:<\/strong> 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.<\/li>\n<\/ul>\n<p>At first, one would think this (SQLite back-end with abbreviated names used as an example here) will do the trick:<\/p>\n<p><code>\/\/ <em>Connector.h:<\/em><br \/>\n<span style=\"color: #0000ff;\"> struct<\/span> SQLite_API SQLiteRegistrator<br \/>\n{<\/code><\/p>\n<p style=\"padding-left: 30px;\"><code>SQLiteRegistrator()<br \/>\n{<br \/>\nSQLite::Connector::registerConnector();<br \/>\n}<\/code><\/p>\n<p style=\"padding-left: 30px;\"><code>~SQLiteRegistrator()<br \/>\n{<br \/>\nSQLite::Connector::unregisterConnector();<br \/>\n}<\/code><\/p>\n<p>};<br \/>\n<code><br \/>\n<span style=\"color: #0000ff;\"> extern<\/span> <span style=\"color: #993366;\">\"C\"<\/span> <span style=\"color: #0000ff;\">struct<\/span> SQLite_API SQLiteRegistrator sqliteRegistrator;<\/code><\/p>\n<p><code> <\/code><\/p>\n<p><code>\/\/ <em>Connector.cpp:<\/em><br \/>\nSQLiteRegistrator sqliteRegistrator;<\/code><\/p>\n<p>Alas, MSVC will disregard your wishes in both static and dynamic library builds when it sees that the registrator is &#8220;not used&#8221; anywhere. Luckily, there&#8217;s a way to force the linkage:<\/p>\n<p><code><span style=\"color: #0000ff;\">#pragma<\/span>(<span style=\"color: #000000;\">comment<\/span> (linker, <span style=\"color: #993366;\">\"\/include:_sqliteRegistrator\"<\/span>)<\/code><\/p>\n<p>With some ifdef-ing for 64-bit (no underscore decoration) and dynamic exports, it turns out that the task is achievable:<\/p>\n<p><code><span style=\"color: #0000ff;\">#pragma<\/span>(comment (linker, <span style=\"color: #993366;\">\"\/export:sqliteRegistrator\"<\/span>)<\/code><\/p>\n<p>So, now we have a way to force initialization without having to explicitly call registerConnector from user code (or peppering library with initialization code).<\/p>\n<p>Details are in <a href=\"https:\/\/github.com\/pocoproject\/poco\/blob\/d6042065eca4f90b4846f1788ffa07716b465618\/Data\/SQLite\/include\/Poco\/Data\/SQLite\/Connector.h#L112\">GitHub repo<\/a> (Net and Data back-ends only at the time of this writing).<\/p>\n<p>This modification was tested on Windows, Mac and Linux, static and shared builds; I&#8217;m putting a word out to hear comments and make sure I did not miss something important, so suggestions are more than welcome. I&#8217;d like to have this in the upcoming\u00a0<a href=\"https:\/\/github.com\/pocoproject\/poco\/issues?milestone=5&amp;state=open\">1.5.2<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In some of POCO libraries (Net on Windows, Data back-ends, Crypto, NetSSL &#8230;), there is a need for early library initialization. This task has been done so far in a couple of ways (neither elegant) &#8211; we either (1) call initialization (repeatedly) from some strategic points in the library (Net, SSL) that we know will [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,26],"tags":[],"class_list":["post-741","post","type-post","status-publish","format-standard","hentry","category-development","category-tips-tricks"],"_links":{"self":[{"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/741","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=741"}],"version-history":[{"count":50,"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/741\/revisions"}],"predecessor-version":[{"id":791,"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/741\/revisions\/791"}],"wp:attachment":[{"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=741"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=741"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pocoproject.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=741"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}