Thread overview
gdc so files
Jan 03, 2007
Sclytrack
Jan 03, 2007
Kirk McDonald
Jan 12, 2007
sclytrack
Jan 12, 2007
Kirk McDonald
January 03, 2007
With dmd I had some trouble with so files. I could add plain functions in them but once I started adding a class it went completely bezurk. I was informed that this was due to dmd not supporting the linux so file format.

Now with version 1.0 I decided to give gdc 0.21 a try. I made a class and an interface like this.

module gui;

interface ICaption
{
	char [] getCaption();
	void setCaption(char []);
}



class Window:ICaption {
private:
	char [] _caption;
public:
	void setCaption(char [] caption)
	{
		_caption = caption;
	}
	char [] getCaption()
	{
		return _caption;
	}
}


The above file is the file that goes into the so library, called libgui.so
I get an access violation when I try the interface from the
libgui.so file.

import std.stdio;
import gui;

int main()
{
	Window test = new Window();
	test.setCaption("Access via interface gives me a violation");
	ICaption itest = test;
	       //next line gets access violation
	writefln(itest.getCaption());
               //previous line Access violation via ICaption
	return 0;
}


I like listing the complete documentation. So here is the makefile I used.

all: main.o libgui.so
#	cc -o main main.o -lpthread -ldl -lm -lgphobos -L. -lgui
	gdc -o main main.o -L. -lgui

main.o: main.d
	gdc -c main.d

libgui.so: gui.o
	gdc -shared -o libgui.so gui.o

gui.o: gui.d
	gdc -c -fPIC gui.d


I was wondering is this the right method of doing .so files? Because in the windows dll example one starts another garbage collector. Here no extra garbage collector is started, or not that I'm aware of.

In the likely event that I won't thank you afterwards.

     Thanks in advance, Sclytrack


Go D, Go !!!
January 03, 2007
Sclytrack wrote:
> I was wondering is this the right method of doing .so files? Because in the
> windows dll example one starts another garbage collector. Here no extra
> garbage collector is started, or not that I'm aware of.
> 
> In the likely event that I won't thank you afterwards.
> 
>      Thanks in advance, Sclytrack
> 
> 
> Go D, Go !!!

Here is Pyd's "boilerplate" module for compiling .so's on Linux. As the comments note, it has some problems:

/*python_so_linux_boilerplate.d*/
// This file requires the .so be compiled with '-nostartfiles'.
// Also note that this is inferior to the Windows version: it does not call the
// static constructors or unit tests. As far as I can tell, this can't be done
// until Phobos is updated to explicitly allow it.
extern(C) {

void gc_init();
void gc_term();

void _init() {
    gc_init();
}

void _fini() {
    gc_term();
}

} /* extern(C) */
/*EOF*/

_init and _fini are special functions in shared objects which are called on initialization and finalization of the library. At some point I'll be fleshing this thing out more (I think I now know how to add static constructor and unittest support, for instance).

The -nostartfiles point is important: gcc has default versions of these functions that it will want to link in. If you end up using both this and GCC's version, it gets very confused. -nostartfiles tells it to not use the defaults, so these can be used instead.

These days, _init and _fini are deprecated in favor of some built-in GCC macros. These are obviously not available in D. Their use in Pyd is safe, since the only thing loading the shared object is Python, which is quite good about calling these functions. The concern is that it is possible for programs to load an .so and somehow skip the call to one or the other of _init or _fini. I am not sure quite how serious of a concern it is; perhaps someone more familiar with the problem can chime in.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
January 12, 2007
> The -nostartfiles point is important: gcc has default versions of these functions that it will want to link in. If you end up using both this and GCC's version, it gets very confused. -nostartfiles tells it to not use the defaults, so these can be used instead.
> 
> These days, _init and _fini are deprecated in favor of some built-in GCC macros. These are obviously not available in D. Their use in Pyd is

1) More Information

I wish there was some more information about
shared libraries for linux on "some" place.

Maybe with linking with a C file, for the
__attribute__((constructor))

Since gcc is readily available on linux


2) Shared Library _minit() and _moduleCtors()

I don't find the _minit() routine, in what file is it located?
What does _moduleCtor() do exactly, does anybody know?

These two routines are called in the windows DLL version.

The two routines above don't appear to be called
in the PyD (linux) project. (nice project by the way, and thanks
the reference to _init() and _fini() )

I've linked it with the so file and the static this()
and ~this() appear to be called of the from the module in the shared library. Automatically. Without me telling to do so.

Just wondering whether the _moduleCtor() calls these static this()
or not. For me it segfaults
on that routine, but I don't have the _minit().

January 12, 2007
sclytrack wrote:
> Kirk McDonald wrote:
>>The -nostartfiles point is important: gcc has default versions of these functions that it will want to link in. If you end up using both this and GCC's version, it gets very confused. -nostartfiles tells it to not use the defaults, so these can be used instead.
>>
>>These days, _init and _fini are deprecated in favor of some built-in GCC macros. These are obviously not available in D. Their use in Pyd is 
> 
> 
> 1) More Information
> 
> I wish there was some more information about
> shared libraries for linux on "some" place.
> 
> Maybe with linking with a C file, for the
> __attribute__((constructor))
> 
> Since gcc is readily available on linux
> 

This is certainly possible. I did not go this route in Pyd, as sticking with D for everything makes compilation that much simpler.

> 
> 2) Shared Library _minit() and _moduleCtors()
> 
> I don't find the _minit() routine, in what file is it located?
> What does _moduleCtor() do exactly, does anybody know? 
> 

You may find the following file in your DMD distribution useful:
dmd/src/phobos/internal/dmain2.d

When a D program is started, the actual entry point is the extern(C) main function in that file, which in turn calls the one you define in your program. That is where the calls to gc_init and all the rest are made for regular executables. (It also does some other things, like run main() inside an exception-safe environment, and convert int argc, char** argv to char[][] args.)

> These two routines are called in the windows DLL version.
> 
> The two routines above don't appear to be called
> in the PyD (linux) project. (nice project by the way, and thanks the reference to _init() and _fini() )
> 

Correct: Pyd does not call _init and _fini. Linux (or perhaps Python) calls them when an extension using Pyd is loaded. Pyd (or, more properly, CeleriD, which is Pyd's build utility) merely makes sure they are linked in to the .so.

> I've linked it with the so file and the static this()
> and ~this() appear to be called of the from the module in the shared library. Automatically. Without me telling to do so.
> 
> Just wondering whether the _moduleCtor() calls these static this()
> or not. For me it segfaults
> on that routine, but I don't have the _minit().
> 

The dmain2.d file leads me to believe that _minit() is only available on Windows. I haven't played with this stuff on Linux since I wrote that Linux boilerplate file, so I forget the details of what is called and what isn't.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org