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



Reply via email to