Linux Dynamic Loading of shared libraries

Anthony Goins neontotem at gmail.com
Mon Mar 10 00:55:46 PDT 2014


On Monday, 10 March 2014 at 06:38:35 UTC, Steve Teale wrote:
> On Sunday, 9 March 2014 at 14:09:28 UTC, Tolga Cakiroglu wrote:
>
>>
>> For this, you create an "Interface" that matches to the method 
>> declaration of your class. But notice that instead of defining 
>> methods, you will define attributes those types' match to that 
>> class's methods. I did this before and it works. At least with 
>> Posix "dlsym" function's help.
>
> OK, so then what goes wrong here:
>
> module exta;
>
> class ExtA
> {
>    int n;
>    this(int _n) { n = _n; }
>
>    int foo() { return ++n; }
> }
>
> ExtA getInstance(int n)
> {
>    return new ExtA(n);
> }
>
> compiled with:
> dmd exta.d -c -fPIC -shared
> dmd exta.o -shared -defaultlib=libphobos2.so -L-rpath=.
>
> module main;
> import core.runtime;
> import std.stdio;
>
> extern(C) void* dlsym(void*, const char*);
> extern(C) void dlclose(void*);
>
> interface ExtA
> {
>    int foo();
> }
>
> void main() {
>    void* lib = Runtime.loadLibrary("exta.so");
>    if (lib is null)
>    {
>       writeln("library not loaded");
>       return;
>    }
>    writeln("loaded");
>
>    void* vp = dlsym(lib, 
> "_D4exta11getInstanceFiZC4exta4ExtA\0".ptr);
>    if (vp is null)
>    {
>       writeln("symbol not found");
>       return;
>    }
>    writeln("got symbol");
>    ExtA function(int) f = cast(ExtA function(int)) vp;
>    ExtA x = f(42);
>    if (x is null)
>    {
>       writeln("no class object");
>       return;
>    }
>    int n = x.foo();
>    writefln("n = %d", n);
>    Runtime.unloadLibrary(lib);
> }
>
> compiled with:
> dmd -c main.d
> dmd main.o -L-ldl -defaultlib=libphobos2.so -L-rpath=.
>
> output:
> loaded
> got symbol
> n = 9
> Segmentation fault (core dumped)
>
> The answer should be 43. The segfault happens on the 
> Runtime.unloadLibrary(lib); call.
>
> Any ideas?
>
> Steve

confusion between main.Exta and exta.ExtA
following worked for me

module exta;

import main;

//===========================================================
class ExtA : ExtA_IF
{
     int n;
     this(int _n) { n = _n; }

     int foo() { return ++n; }
}

ExtA_IF getInstance(int n)
{
     return new ExtA(n);
}
//=============================================================


//==============================================================
module main;
import core.runtime;
import std.stdio;

extern(C) void* dlsym(void*, const char*);
extern(C) void dlclose(void*);

interface ExtA_IF
{
     int foo();
}

void main() {
     void* lib = Runtime.loadLibrary("exta.so");
     if (lib is null)
     {
        writeln("library not loaded");
        return;
     }
     writeln("loaded");

     //use extern (C) to avoid mangling
     void* vp = dlsym(lib,
"_D4exta11getInstanceFiZC4main7ExtA_IF\0".ptr);
     if (vp is null)
     {
        writeln("symbol not found");
        return;
     }
     writeln("got symbol");
     ExtA_IF function(int) f = cast(ExtA_IF function(int)) vp;
     ExtA_IF x = f(42);
     if (x is null)
     {
        writeln("no class object");
        return;
     }
     int n = x.foo();
     writefln("n = %d", n);

     // or free or destroy or whatever it's supposed to be to
     //to avoid the seg fault  (bug?)
     delete x;
     Runtime.unloadLibrary(lib);
}


More information about the Digitalmars-d-learn mailing list