www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - undefined symbol: _Dmain when loading library at runtime on Linux

reply "FreeSlave" <freeslave93 gmail.com> writes:
//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:

#! /bin/bash
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
parent reply "David Nadlinger" <code klickverbot.at> writes:
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
parent "FreeSlave" <freeslave93 gmail.com> writes:
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?

 David
Yes, 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