Desperately looking for a work-around to load and unload D shared libraries from C on OSX
bitwise via Digitalmars-d
digitalmars-d at puremagic.com
Thu Sep 17 01:09:52 PDT 2015
On Thursday, 17 September 2015 at 06:40:56 UTC, ponce wrote:
> On Wednesday, 16 September 2015 at 23:24:29 UTC, bitwise wrote:
>>
>> I was trying to solve this one myself, but the modifications
>> to DMD's backend that are needed are out of reach for me right
>> now.
>>
>> If you're willing to build your own druntime, you may be able
>> to get by.
>
> I'd prefer a solution that works with existing compilers, but
> maybe building a custom LDC is possible if I figure it out.
Unfortunately, this is a complex problem and you can't just flip
a few switches and make it work.
> In practive I've found that the D shared libraries I produce
> can be dlopen/dlclose any number of times, simultaneous too.
> Using both LDC and DMD, don't know why it works.
> The thing that doesn't work is the C host program dlopen'ing
> the shared library, dlclose it, then dlopen another shared
> library written in C.
Calling dlopen won't initialize the runtime in the shared
library. Although your program doesn't crash, you may find that
it does once you start calling into the shared lib... or it may
leak memory because the GC was never initialized. You can call
Runtime.initialize() from druntime yourself, but as you know,
there is the callback issue.
I think LDC may be farther along in terms of shared library
support. You may want to ask David Nadlinger about this. I think
the problem with LDC was that it only supported statically loaded
shared libs for osx. I'm not sure if this is still the case, but
it looks like it:
https://github.com/ldc-developers/druntime/blob/002d0aed65cd24dfcbbc782d9aed2f9112f27b4e/src/rt/sections_ldc.d#L372
>> Anyways, when main() of a D program runs, it calls rt_init()
>> and rt_term(). If you don't have a D entry point in your
>> program, you have to retrieve these from your shared lib(which
>> has druntime statically linked) using dlsym() and call them
>> yourself.
>
> I don't control the host program. My shared libs do have an
> entrypoint, from which I call Runtime.initialize().
>
> I can also use LDC global constructor/destructor to call
> Runtime.initialize / Runtime.terminate, but it doesn't work any
> better because of the callback.
I don't think there is any way around this beside building a
custom runtime and implementing the function I suggested.
> Thanks for your answer. This is really helpful, though I don't
> understand the first thing about what images, headers and
> sections are in this context.
As a last resort, you may be able to use OSX Distributed Objects,
depending on what your shared library does. This is basically a
wrapper around linux pipes, but with a simple RPC-like interface.
Depending on how much talk there is between the host program and
your shared lib, this may or may not be a good solution.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DistrObjects/DistrObjects.html
Basically, you would make an Objective-C shared library with a C
interface, into which the host program could call. This shared
library would then spawn a second process as needed, which would
load the D shared library. You would then use distributed objects
to call from the Objective-C shared library to the D shared
library. When you were done with the D shared library, you would
simply terminate the second process.
Bit
More information about the Digitalmars-d
mailing list