main.d: import core.stdc.stdio; import core.stdc.stdlib; import core.sys.posix.dlfcn; extern (C) int dll(); int main() { printf("+main()\n"); void *lh = dlopen("libdll.so", RTLD_LAZY); if (!lh) { fprintf(stderr, "dlopen error: %s\n", dlerror()); exit(1); } printf("libdll.so is loaded\n"); int function() fn = cast(int function())dlsym(lh, "dll"); char *error = dlerror(); if (error) { fprintf(stderr, "dlsym error: %s\n", error); exit(1); } printf("dll() function is found\n"); fn(); printf("unloading libdll.so\n"); dlclose(lh); printf("-main()\n"); return 0; } dll.d: import core.stdc.stdio; extern (C) int dll() { printf("dll()\n"); return 0; } static this() { printf("libdll.so construction\n"); } static ~this() { printf("libdll.so destruction\n"); } Build: dmd -c dll.d -fPIC dmd -oflibdll.so dll.o -shared -defaultlib=libphobos2.so -L-rpath=/home/walter/cbx/mars/phobos/generated/linux/release/64 dmd -c main.d dmd main.o -L-ldl -defaultlib=libphobos2.so -L-rpath=.:/home/walter/cbx/mars/phobos/generated/linux/release/64 ./main Results: +main() libdll.so is loaded dll() function is found dll() unloading libdll.so -main() Note that the module constructors and destructors are not run. This is a bug.
This was implemented by https://github.com/D-Programming-Language/druntime/pull/593 (https://github.com/D-Programming-Language/druntime/commit/73d067fd04ed8c9588c5ae09ebe48fdb1b528793). Works for me, I had to change dlopen("libdll.so", RTLD_LAZY) to dlopen("./libdll.so", RTLD_LAZY) though. +main() libdll.so construction libdll.so is loaded dll() function is found dll() unloading libdll.so libdll.so destruction -main() Note: It's better to use Runtime.load/unloadLibrary [¹] instead of dlopen/dlclose b/c then we can run the TLS ctors/dtors without holding the loader lock, thus avoiding a common source of deadlocks and reducing possible contention. [¹]: http://dlang.org/phobos/core_runtime.html#.Runtime.loadLibrary rt_loadLibrary or core.runtime.Runtime.loadLibrary.