On 07/26/2014 12:15 AM, Andrei Alexandrescu wrote:
Hello,


We've just open-sourced another D project at Facebook (just a developer
beta), an ODBC driver for the Presto database engine:
https://github.com/prestodb/presto-odbc.

The Windows version works well now, and Mark Isaacson (the author of the
driver and incidentally my intern) is working already on the OSX port
using iODBC. We've hit a number of issues, the most basic one being that
shared static this() initializers don't seem to be called for our driver.

Could you folks help us out?


Thanks,

Andrei

So this is a statically linked shared D library with a C interface, right? This is the only kind of shared libraries currently supported on OSX. It means that each lib comes with it's own private copy of phobos/druntime, so you got to be careful to not run into ODR issues (https://issues.dlang.org/show_bug.cgi?id=7020).

Short answer:

Load the library, get the address of rt_init and call it from your C program.

Long answer:

It's a bad practice to automatically initialize dynamic libraries during loading because it can lead to deadlocks (on the runtime loader lock). Also loading/unloading is globally synchronized and you don't want to perform long-running computations while holding the loader lock.

The common pattern is to provide init/fini functions in your library which are explicitly called by a user. So you should add presto_init/presto_fini functions and call Runtime.initialize()/Runtime.finalize() within those functions. When the C program loads your library it will have to call presto_init before using it and presto_fini before unloading it. Here is an example of this pattern https://github.com/D-Programming-Language/druntime/blob/dc559c3ef2916102c6f295d70c3941644e545bf2/test/shared/src/host.c.

If you absolutely need automatic initialization, you can add a C file with constructor/destructor functions to your project.

extern void rt_init();
extern void rt_term();

void presto_init() __attribute__((constructor));
void presto_init()
{
  rt_init();
  //...
}

void presto_fini() __attribute__((destructor));
void presto_fini()
{
  //...
  rt_term();
}

The runtime linker will call those functions during loading/unloading.
But once again, we went with explicit initialization because implicit init/fini didn't work out too well (https://issues.dlang.org/show_bug.cgi?id=11378).

Reply via email to