digitalmars.D.ldc - undefined symbol: _Dmain when loading library at runtime on Linux
- FreeSlave (72/72) Sep 29 2013 //mod.d:
- David Nadlinger (7/7) Sep 29 2013 The short answer is: Shared D libraries, especially dynamically loading
- FreeSlave (19/27) Sep 29 2013 Yes, libdl. dlfcn if header's name. Well, this "by accident" is
//mod.d: module mod; export extern(C) int testThrow() { throw new Exception("Just a test"); } //main.d: import std.stdio; import std.c.linux.linux; import std.string : toStringz; import std.conv : to; int main(string args[]) { version(Binding) { version(LDC) { string name = "./libmodldc.so"; } else { string name = "./libmod.so"; } void* handle = dlopen(toStringz(name), RTLD_LAZY); if (!handle) { writeln(to!string(dlerror())); return 1; } auto testThrow = cast(void function())dlsym(handle, toStringz("testThrow")); if (!testThrow) { writeln(to!string(dlerror())); return 1; } } else { import mod; } try { testThrow(); } catch(Exception e) { writeln(e.msg); } return 0; } Script to build them all and start executables in place: export LD_LIBRARY_PATH=. ldmd2 -shared -fPIC mod.d -oflibmodldc.so ldmd2 main.d -L-L. -L-lmodldc -ofmainldc ldmd2 main.d -version=Binding -ofmainldcbind dmd -shared -fPIC mod.d -oflibmod.so dmd main.d -L-L. -L-lmod -ofmain dmd main.d -version=Binding -ofmainbind -L-ldl ./main ./mainbind ./mainldc ./mainldcbind Both main and mainldc work fine (those which was linked against shared library). But when I start "bind" version compiled by ldmd2 I got error: ./libmodldc.so: undefined symbol: _Dmain If I add -L--export-dynamic option to command line then it works fine. But dmd does not require this option - mainbind has correct output. Another strange thing is that ldmd2 does not require linking against dlfcn library.
Sep 29 2013
The short answer is: Shared D libraries, especially dynamically loading them, is not supported by LDC. We are going implement this once upstream druntime actually supports runtime loading (2.064). So, even the versions that "work fine" do so just by accident. There are much bigger problems that this, even with compile-time linked shared libraries. dlfcn - you mean libdl? David
Sep 29 2013
On Sunday, 29 September 2013 at 23:40:21 UTC, David Nadlinger wrote:The short answer is: Shared D libraries, especially dynamically loading them, is not supported by LDC. We are going implement this once upstream druntime actually supports runtime loading (2.064). So, even the versions that "work fine" do so just by accident. There are much bigger problems that this, even with compile-time linked shared libraries. dlfcn - you mean libdl? DavidYes, libdl. dlfcn if header's name. Well, this "by accident" is not so bad, I've just checked dynamic loading of C++ class in ldmd2 - it works. But I'm not sure how to build C++ library to set D function as exception handler properly (for rethrowing). It worked with dmd in this way: //dmd cppexception.d -c extern(C) void cppRethrower() { throw new Exception("Cpp exception"); } //g++ cppfiles.cpp cppexception.o extern "C" { void cppRethrower(); } std::set_terminate(cppRethrower); //somewhere Anyway, wait for good support of shared libraries by all D compiler, I'm very interested in that because I write library helping to load plugins at runtime ( https://bitbucket.org/FreeSlave/dido )
Sep 29 2013