Equivalent of DllMain for OSX dynamic libraries?
Martin Nowak via Digitalmars-d
digitalmars-d at puremagic.com
Tue Jul 29 15:52:06 PDT 2014
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).
More information about the Digitalmars-d
mailing list