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