Re: Linux Dynamic Loading of shared libraries

2014-07-29 Thread seany via Digitalmars-d-learn

Bless you, mate. You described precisely what I was looking for.

Nonetheless, I am still looking for a load and unload command to 
select and reject plugins in runtime.


Re: Linux Dynamic Loading of shared libraries

2014-07-29 Thread Sean Kelly via Digitalmars-d-learn

On Monday, 10 March 2014 at 11:59:20 UTC, Steve Teale wrote:


Note that there is no call to Runtime.unloadLibrary(). The 
assumption her is that once the plugin has been loaded it will 
be there for the duration of the program. If you want to unload 
it you'll probably have to make sure the plugin object is 
purged from memory first, and I have not discovered how to do 
that yet ;=(


A long time ago, Andrei suggested creating a GC interface for 
mapped memory.  I think something similar might be appropriate 
here.  Perhaps the location of instantiated classes could be 
determined by their vtbl pointer?  Then the entire vtbl range 
could be treated as a dynamically allocated struct of sorts, and 
its dtor would queue up a job to unmap the library after 
collection is complete (ie. not immediately, since the order of 
destruction during a collection is undefined).


So... (just thinking out loud) when a library is loaded, you 
basically perform an in-place construction of this LoadedLibrary 
struct on top of the vtbl range.  You'd need an interface similar 
to the GC tracks memory mapped files idea to tell the GC to 
track references to this range of memory that lives outside its 
own pool set, and then some kind of post-collection job queue 
that's externally appendable so the LoadedLibrary struct could 
add an unload call when it's collected.  Heck, we could really 
handle all dtors this way, so normal dtors would be inserted at 
the front of the list and special cases like this would be 
inserted at the back.


It doesn't sound tremendously difficult, though we'd need the 
memory-mapped file support API first.  Is there something I'm 
missing that makes this unfeasible?


Re: Linux Dynamic Loading of shared libraries

2014-07-29 Thread Carl Sturtivant via Digitalmars-d-learn

Can't retrieve the archive from that URL.
britseyeview.com/plugin101.tar.bz2
Interested, so can you please fix?

On Monday, 10 March 2014 at 11:59:20 UTC, Steve Teale wrote:

On Sunday, 9 March 2014 at 12:07:22 UTC, Steve Teale wrote:

Now suppose that my D shared library contains a class, rather 
that just module ctors/dtors, how do I go about creating an 
instance of that class and using its methods?


After wandering down several dead-end paths, and help from 
other contributors, I have finally come up with something that 
looks like the basis of a plugin pattern for Linux DMD using 
shared objects (.so files). This is somewhat long for a forum 
post. You can download this readme and the associated files 
from britseyeview.com/plugin101.tar.bz2


To get started, you need a base class that provides 
declarations for all functions that the plugin will be allowed 
to use externally. Why base class, and not interface? Well I 
guess because interfaces don't provide any information about 
data. If you create a shared library based on an interface, 
then all the shared object methods that reference data in the 
class that implements the interface fail miserably. I'm sure 
someone will explain why - probably some obvious thing I have 
overlooked.


OK, so my base class is:

module plugin;

class Plugin
{
   int n;
   this(int _n) { n = _n; }

   int foo() { return int.min; }
   void bar() {}
}


The class that implements this base in the shared library is:

module exta;
import plugin;
import std.stdio;
import std.math;

class ExtA: Plugin
{
   double d;
   this(int n) { super(n); d = PI; }

   override int foo() { return ++n; }
   override void bar() { writefln(Done my thing (%f), d); }
}

Plugin getInstance(int n)
{
   return new ExtA(n);
}

shared static this() {
  writeln(exta.so shared static this);
}

shared static ~this() {
  writeln(exta.so shared static ~this);
}

The module ctor/dtor are included because that has become 
conventional in discussions about dynamic loading. Otherwise, 
the so has the class implementation - ExtA, and a shared method 
to create an instance of same. It includes references to 
methods in Phobos.


The test program is as follows:

module main;
import core.runtime;
import std.stdio;
import plugin;

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

alias Plugin function(int) pfi;

Plugin getPlugin(string name)
{
   void* lib = Runtime.loadLibrary(name~.so);
   if (lib is null)
   {
  writeln(failed to load plugin shared object);
  return null;
   }

   void* vp = dlsym(lib, 
_D4exta11getInstanceFiZC6plugin6Plugin\0.ptr);

   if (vp is null)
   {
  writeln(plugin creator function not found);
  return null;
   }
   pfi f = cast(pfi) vp;
   Plugin x = f(42);
   if (x is null)
   {
  writeln(creation of plugin failed);
  return null;
   }
   return x;
}

void main()
{
   Plugin x = getPlugin(exta);
   int n = x.foo();
   writefln(n = %d, n);
   x.bar();
}

The long symbol name used in the dlsym() call is of course from 
the .map file generated when the .so file is created


These can be built using the following primitive makefile, 
whose main purpose is to spell out the required compiler flags:


main :
dmd -c plugin.d
dmd -c -shared -fPIC exta.d
dmd exta.o -shared -defaultlib=libphobos2.so -map
dmd -c main.d
dmd main.o plugin.o -L-ldl -defaultlib=libphobos2.so -L-rpath=.

This assumes that the plugins will be in the same directory as 
the executable (rpath=.).


Note that there is no call to Runtime.unloadLibrary(). The 
assumption her is that once the plugin has been loaded it will 
be there for the duration of the program. If you want to unload 
it you'll probably have to make sure the plugin object is 
purged from memory first, and I have not discovered how to do 
that yet ;=(


Steve




Re: Linux Dynamic Loading of shared libraries

2014-03-10 Thread Steve Teale

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




Re: Linux Dynamic Loading of shared libraries

2014-03-10 Thread Anthony Goins

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);
}


Re: Linux Dynamic Loading of shared libraries

2014-03-10 Thread Steve Teale

On Sunday, 9 March 2014 at 12:07:22 UTC, Steve Teale wrote:

Now suppose that my D shared library contains a class, rather 
that just module ctors/dtors, how do I go about creating an 
instance of that class and using its methods?


After wandering down several dead-end paths, and help from other 
contributors, I have finally come up with something that looks 
like the basis of a plugin pattern for Linux DMD using shared 
objects (.so files). This is somewhat long for a forum post. You 
can download this readme and the associated files from 
britseyeview.com/plugin101.tar.bz2


To get started, you need a base class that provides declarations 
for all functions that the plugin will be allowed to use 
externally. Why base class, and not interface? Well I guess 
because interfaces don't provide any information about data. If 
you create a shared library based on an interface, then all the 
shared object methods that reference data in the class that 
implements the interface fail miserably. I'm sure someone will 
explain why - probably some obvious thing I have overlooked.


OK, so my base class is:

module plugin;

class Plugin
{
   int n;
   this(int _n) { n = _n; }

   int foo() { return int.min; }
   void bar() {}
}


The class that implements this base in the shared library is:

module exta;
import plugin;
import std.stdio;
import std.math;

class ExtA: Plugin
{
   double d;
   this(int n) { super(n); d = PI; }

   override int foo() { return ++n; }
   override void bar() { writefln(Done my thing (%f), d); }
}

Plugin getInstance(int n)
{
   return new ExtA(n);
}

shared static this() {
  writeln(exta.so shared static this);
}

shared static ~this() {
  writeln(exta.so shared static ~this);
}

The module ctor/dtor are included because that has become 
conventional in discussions about dynamic loading. Otherwise, the 
so has the class implementation - ExtA, and a shared method to 
create an instance of same. It includes references to methods in 
Phobos.


The test program is as follows:

module main;
import core.runtime;
import std.stdio;
import plugin;

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

alias Plugin function(int) pfi;

Plugin getPlugin(string name)
{
   void* lib = Runtime.loadLibrary(name~.so);
   if (lib is null)
   {
  writeln(failed to load plugin shared object);
  return null;
   }

   void* vp = dlsym(lib, 
_D4exta11getInstanceFiZC6plugin6Plugin\0.ptr);

   if (vp is null)
   {
  writeln(plugin creator function not found);
  return null;
   }
   pfi f = cast(pfi) vp;
   Plugin x = f(42);
   if (x is null)
   {
  writeln(creation of plugin failed);
  return null;
   }
   return x;
}

void main()
{
   Plugin x = getPlugin(exta);
   int n = x.foo();
   writefln(n = %d, n);
   x.bar();
}

The long symbol name used in the dlsym() call is of course from 
the .map file generated when the .so file is created


These can be built using the following primitive makefile, whose 
main purpose is to spell out the required compiler flags:


main :
dmd -c plugin.d
dmd -c -shared -fPIC exta.d
dmd exta.o -shared -defaultlib=libphobos2.so -map
dmd -c main.d
dmd main.o plugin.o -L-ldl -defaultlib=libphobos2.so -L-rpath=.

This assumes that the plugins will be in the same directory as 
the executable (rpath=.).


Note that there is no call to Runtime.unloadLibrary(). The 
assumption her is that once the plugin has been loaded it will be 
there for the duration of the program. If you want to unload it 
you'll probably have to make sure the plugin object is purged 
from memory first, and I have not discovered how to do that yet 
;=(


Steve


Linux Dynamic Loading of shared libraries

2014-03-09 Thread Steve Teale

Martin Nowak's Gihub druntime Page has

module main;
import core.runtime, core.thread;

void main() {
auto lib = Runtime.loadLibrary(./liba.so);
auto thr = new Thread({
auto lib = Runtime.loadLibrary(./liba.so);
Runtime.unloadLibrary(lib);
});
thr.start();
thr.join();
Runtime.unloadLibrary(lib);
}

module liba;
import std.stdio;

shared static this() { writeln(shared static this()); }
shared static ~this() { writeln(shared static ~this()); }
static this() { writeln(static this()); }
static ~this() { writeln(static ~this()); }

Now suppose that my D shared library contains a class, rather 
that just module ctors/dtors, how do I go about creating an 
instance of that class and using its methods?


Steve


Re: Linux Dynamic Loading of shared libraries

2014-03-09 Thread Tolga Cakiroglu


Now suppose that my D shared library contains a class, rather 
that just module ctors/dtors, how do I go about creating an 
instance of that class and using its methods?


Steve


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.


Re: Linux Dynamic Loading of shared libraries

2014-03-09 Thread Anthony Goins

On Sunday, 9 March 2014 at 12:07:22 UTC, Steve Teale wrote:

Martin Nowak's Gihub druntime Page has

module main;
import core.runtime, core.thread;

void main() {
auto lib = Runtime.loadLibrary(./liba.so);
auto thr = new Thread({
auto lib = Runtime.loadLibrary(./liba.so);
Runtime.unloadLibrary(lib);
});
thr.start();
thr.join();
Runtime.unloadLibrary(lib);
}

module liba;
import std.stdio;

shared static this() { writeln(shared static this()); }
shared static ~this() { writeln(shared static ~this()); }
static this() { writeln(static this()); }
static ~this() { writeln(static ~this()); }

Now suppose that my D shared library contains a class, rather 
that just module ctors/dtors, how do I go about creating an 
instance of that class and using its methods?


Steve

If you know the fully qualified name of the class and an interface
auto newClassIF = 
cast(interfacename)object.factory(libmodule.libclass);


Re: Dynamic loading of shared libraries.

2011-06-17 Thread Jacob Carlborg

On 2011-06-13 16:19, Robert Clipsham wrote:

On 13/06/2011 14:32, Andrei Alexandrescu wrote:

Two questions - first, what steps do we need to take to convince the
linker call from within dmd to work as above?

Second, how about the converse - loading a shared library from a program
written in either C or D?


I was under the impression that dmd couldn't produce shared libraries in
its current state - doesn't its output clobber the PIC register or
something when compiling with -fPIC?

http://d.puremagic.com/issues/show_bug.cgi?id=4583


Thanks,

Andrei


That's correct. And the runtime also will need a couple of changes as 
well. Like initializing module info, i.e. module constructors, exception 
handling tables and so on.


--
/Jacob Carlborg


Re: Dynamic loading of shared libraries.

2011-06-17 Thread Jacob Carlborg

On 2011-06-13 18:19, Andrei Alexandrescu wrote:

On 6/13/11 10:33 AM, Jens Mueller wrote:

Andrei Alexandrescu wrote:

On 6/13/11 4:27 AM, Jens Mueller wrote:

Steve Teale wrote:

Can DMD D2/Linux do this yet?


dmd can't do it yet. But if all you want is to link a against a shared
library you can try the following:

1. Create a shared library
$ gcc -m64 -fPIC -shared shared.c -o libshared.so

2. Building (without linking using dmd)
$ dmd -m64 -c dynamic.d -ofdynamic.o

3. Use gcc as linker
$ gcc -m64 dynamic.o /path/to//libphobos2.a -L. -lshared -lrt -o
dynamic

4. Execute
$ ./dynamic
Hello from shared

I attached the files shared.c and dynamic.d, if you want to try
yourself.

Jens


Jens,


Two questions - first, what steps do we need to take to convince the
linker call from within dmd to work as above?


Never thought about that. Just tried.
$ dmd -m64 dynamic.o /path/to/libphobos2.a -L-L. -L-lshared -L-lrt
-ofdynamic
works.


Great. Wonder why the path to Phobos is still needed - does using -L
preclude all implicit uses of it?


Second, how about the converse - loading a shared library from a
program written in either C or D?


Don't know exactly what you mean. As far as I know dmd is not able to
generate shared libraries. Is that your question?


Yah, I was wondering if it's just PIC generation or something extra.


Andrei


The runtime needs a couple of changes as well, for example module info, 
i.e. module constructors, exception handling tables and so on.


--
/Jacob Carlborg


Re: Dynamic loading of shared libraries.

2011-06-14 Thread Jens Mueller
Brad Roberts wrote:
 On Mon, 13 Jun 2011, Jens Mueller wrote:
 
  There have been some posts regarding support for shared libraries. On
  top of my head there we're at least 5 things that need to be done to get
  it working.
  $ dmd -m64 -L-shared shared.d -oflibshared.so
  /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: 
  relocation R_X86_64_32S against `__libc_csu_fini' can not be used when 
  making a shared object; recompile with -fPIC
  /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: could not read 
  symbols: Bad value
  collect2: ld returned 1 exit status
  --- errorlevel 1
  
  I do not fully understand the error. But I believe there is something
  wrong with dmd generating PIC.
  
  Jens
 
 When building a shared library, you must build with -fPIC.  That's likely 
 not sufficient to get it actually fully working with dmd.
 
 so:  dmd -m64 -fPIC -L-shared shared.d -oflibshared.so

Yes. I actually built using -fPIC but pasted the wrong line. Anyway both
lines result in the same above error.

 That said, combining not-well-tested .so support with 64 bit is a good way 
 to discover new bugs, so go for it! :)

You say not-well-tested .so support. I thought it's still under
construction. I'm on dmd 2.053.

Jens


Re: Dynamic loading of shared libraries.

2011-06-13 Thread Jens Mueller
Steve Teale wrote:
 Can DMD D2/Linux do this yet?

dmd can't do it yet. But if all you want is to link a against a shared
library you can try the following:

1. Create a shared library
$ gcc -m64 -fPIC -shared shared.c -o libshared.so

2. Building (without linking using dmd)
$ dmd -m64 -c dynamic.d -ofdynamic.o

3. Use gcc as linker
$ gcc -m64 dynamic.o /path/to//libphobos2.a -L. -lshared -lrt -o dynamic

4. Execute
$ ./dynamic
Hello from shared

I attached the files shared.c and dynamic.d, if you want to try
yourself.

Jens
#include stdio.h

void test() {
printf(Hello from shared\n);
}
extern(C) void test();

void main() {
	test();
}


Re: Dynamic loading of shared libraries.

2011-06-13 Thread Andrei Alexandrescu

On 6/13/11 4:27 AM, Jens Mueller wrote:

Steve Teale wrote:

Can DMD D2/Linux do this yet?


dmd can't do it yet. But if all you want is to link a against a shared
library you can try the following:

1. Create a shared library
$ gcc -m64 -fPIC -shared shared.c -o libshared.so

2. Building (without linking using dmd)
$ dmd -m64 -c dynamic.d -ofdynamic.o

3. Use gcc as linker
$ gcc -m64 dynamic.o /path/to//libphobos2.a -L. -lshared -lrt -o dynamic

4. Execute
$ ./dynamic
Hello from shared

I attached the files shared.c and dynamic.d, if you want to try
yourself.

Jens


Jens,


Two questions - first, what steps do we need to take to convince the 
linker call from within dmd to work as above?


Second, how about the converse - loading a shared library from a program 
written in either C or D?



Thanks,

Andrei


Re: Dynamic loading of shared libraries.

2011-06-13 Thread Robert Clipsham

On 13/06/2011 14:32, Andrei Alexandrescu wrote:

Two questions - first, what steps do we need to take to convince the
linker call from within dmd to work as above?

Second, how about the converse - loading a shared library from a program
written in either C or D?


I was under the impression that dmd couldn't produce shared libraries in 
its current state - doesn't its output clobber the PIC register or 
something when compiling with -fPIC?


http://d.puremagic.com/issues/show_bug.cgi?id=4583


Thanks,

Andrei



--
Robert
http://octarineparrot.com/


Re: Dynamic loading of shared libraries.

2011-06-13 Thread Jens Mueller
Andrei Alexandrescu wrote:
 On 6/13/11 4:27 AM, Jens Mueller wrote:
 Steve Teale wrote:
 Can DMD D2/Linux do this yet?
 
 dmd can't do it yet. But if all you want is to link a against a shared
 library you can try the following:
 
 1. Create a shared library
 $ gcc -m64 -fPIC -shared shared.c -o libshared.so
 
 2. Building (without linking using dmd)
 $ dmd -m64 -c dynamic.d -ofdynamic.o
 
 3. Use gcc as linker
 $ gcc -m64 dynamic.o /path/to//libphobos2.a -L. -lshared -lrt -o dynamic
 
 4. Execute
 $ ./dynamic
 Hello from shared
 
 I attached the files shared.c and dynamic.d, if you want to try
 yourself.
 
 Jens
 
 Jens,
 
 
 Two questions - first, what steps do we need to take to convince the
 linker call from within dmd to work as above?

Never thought about that. Just tried.
$ dmd -m64 dynamic.o /path/to/libphobos2.a -L-L. -L-lshared -L-lrt -ofdynamic
works.

 Second, how about the converse - loading a shared library from a
 program written in either C or D?

Don't know exactly what you mean. As far as I know dmd is not able to
generate shared libraries. Is that your question?

Jens


Re: Dynamic loading of shared libraries.

2011-06-13 Thread Andrei Alexandrescu

On 6/13/11 10:33 AM, Jens Mueller wrote:

Andrei Alexandrescu wrote:

On 6/13/11 4:27 AM, Jens Mueller wrote:

Steve Teale wrote:

Can DMD D2/Linux do this yet?


dmd can't do it yet. But if all you want is to link a against a shared
library you can try the following:

1. Create a shared library
$ gcc -m64 -fPIC -shared shared.c -o libshared.so

2. Building (without linking using dmd)
$ dmd -m64 -c dynamic.d -ofdynamic.o

3. Use gcc as linker
$ gcc -m64 dynamic.o /path/to//libphobos2.a -L. -lshared -lrt -o dynamic

4. Execute
$ ./dynamic
Hello from shared

I attached the files shared.c and dynamic.d, if you want to try
yourself.

Jens


Jens,


Two questions - first, what steps do we need to take to convince the
linker call from within dmd to work as above?


Never thought about that. Just tried.
$ dmd -m64 dynamic.o /path/to/libphobos2.a -L-L. -L-lshared -L-lrt -ofdynamic
works.


Great. Wonder why the path to Phobos is still needed - does using -L 
preclude all implicit uses of it?



Second, how about the converse - loading a shared library from a
program written in either C or D?


Don't know exactly what you mean. As far as I know dmd is not able to
generate shared libraries. Is that your question?


Yah, I was wondering if it's just PIC generation or something extra.


Andrei


Re: Dynamic loading of shared libraries.

2011-06-13 Thread Jens Mueller
Andrei Alexandrescu wrote:
 On 6/13/11 10:33 AM, Jens Mueller wrote:
 Andrei Alexandrescu wrote:
 On 6/13/11 4:27 AM, Jens Mueller wrote:
 Steve Teale wrote:
 Can DMD D2/Linux do this yet?
 
 dmd can't do it yet. But if all you want is to link a against a shared
 library you can try the following:
 
 1. Create a shared library
 $ gcc -m64 -fPIC -shared shared.c -o libshared.so
 
 2. Building (without linking using dmd)
 $ dmd -m64 -c dynamic.d -ofdynamic.o
 
 3. Use gcc as linker
 $ gcc -m64 dynamic.o /path/to//libphobos2.a -L. -lshared -lrt -o dynamic
 
 4. Execute
 $ ./dynamic
 Hello from shared
 
 I attached the files shared.c and dynamic.d, if you want to try
 yourself.
 
 Jens
 
 Jens,
 
 
 Two questions - first, what steps do we need to take to convince the
 linker call from within dmd to work as above?
 
 Never thought about that. Just tried.
 $ dmd -m64 dynamic.o /path/to/libphobos2.a -L-L. -L-lshared -L-lrt -ofdynamic
 works.
 
 Great. Wonder why the path to Phobos is still needed - does using -L
 preclude all implicit uses of it?

No. You're right. It works without the path to Phobos.

 Second, how about the converse - loading a shared library from a
 program written in either C or D?
 
 Don't know exactly what you mean. As far as I know dmd is not able to
 generate shared libraries. Is that your question?
 
 Yah, I was wondering if it's just PIC generation or something extra.

There have been some posts regarding support for shared libraries. On
top of my head there we're at least 5 things that need to be done to get
it working.
$ dmd -m64 -L-shared shared.d -oflibshared.so
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: 
relocation R_X86_64_32S against `__libc_csu_fini' can not be used when making a 
shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: could not read 
symbols: Bad value
collect2: ld returned 1 exit status
--- errorlevel 1

I do not fully understand the error. But I believe there is something
wrong with dmd generating PIC.

Jens


Re: Dynamic loading of shared libraries.

2011-06-13 Thread Brad Roberts
On Mon, 13 Jun 2011, Jens Mueller wrote:

 There have been some posts regarding support for shared libraries. On
 top of my head there we're at least 5 things that need to be done to get
 it working.
 $ dmd -m64 -L-shared shared.d -oflibshared.so
 /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: 
 relocation R_X86_64_32S against `__libc_csu_fini' can not be used when making 
 a shared object; recompile with -fPIC
 /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: could not read 
 symbols: Bad value
 collect2: ld returned 1 exit status
 --- errorlevel 1
 
 I do not fully understand the error. But I believe there is something
 wrong with dmd generating PIC.
 
 Jens

When building a shared library, you must build with -fPIC.  That's likely 
not sufficient to get it actually fully working with dmd.

so:  dmd -m64 -fPIC -L-shared shared.d -oflibshared.so

That said, combining not-well-tested .so support with 64 bit is a good way 
to discover new bugs, so go for it! :)

Later,
Brad



Dynamic loading of shared libraries.

2011-06-12 Thread Steve Teale
Can DMD D2/Linux do this yet?


Re: Dynamic loading of shared libraries.

2011-06-12 Thread Adam D. Ruppe
AFAIK, the situation is the same as when you asked last time. Still
on the list.