building shared library from D code to import into cython

Freddy via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Oct 7 15:46:08 PDT 2014


On Tuesday, 7 October 2014 at 20:55:59 UTC, Laeeth Isharc wrote:
> Hi.
>
> I am trying to create a shared library in D linked against 
> phobos so that I may use this in a cython extension module for 
> Python.  Ultimately I would like to be able to use a D class or 
> struct (via the C++ interface) and call it from within cython, 
> since cython classes cannot be instantiated without the gil 
> (and this prevents easy parallelisation).
>
> I feel a bit foolish asking the question as there is a nice 
> example here for working with plain C using dmd as the linker, 
> and using dmd and gcc to create a DMD shared library statically 
> linked to phobos.  However, I have not succeeded in creating a 
> D library statically linked to phobos that works with cython 
> and python,
> http://dlang.org/dll-linux.html#dso7
>
> I tried it first with test C code to make sure I am able to get 
> the C library/cython/Python interaction working.
>
> pytest.c:
> #include <stdio.h>
>
> long pytest(long a)
> {
> 	return a+1;
> }
>
> int main()
> {
> 	long a =pytest(100);
> 	printf("%ld",a);
> 	return 0;
> }
>
>
> pytestpy.pyx:
> cdef extern long pytest(long a)
>
> cpdef pytestpy():
> 	return pytest(109)
>
>
> setup.py:
>
> from distutils.core import setup
> from distutils.extension import Extension
> from Cython.Build import cythonize
>
> setup(
> 		ext_modules = cythonize([
>  				 Extension("pytestpy", ["pytestpy.pyx"],
> 				libraries=["pytest"],
> 				)
>  	]))
>
>
> command line:
> gcc -shared -o libpytest.so pytest.o
> python setup.py build_ext -i
> <copied libpytest.so to /usr/local/lib>
> python
> import pytestpy
> pytestpy.pytestpy()
> <it works>
>
> ----
> now try pytest.d
> import std.stdio;
>
> extern (C) long pytest(long a)
> {
> 	return a*2;
> }
>
> void main()
> {
> 	auto a =pytest(100);
> 	writefln("%d",a);
> }
>
> command line:
> rm pytestd.o
> rm libpytest.so
> rm /usr/local/lib/libpytest.so
> dmd -c pytest.d -fPIC
> gcc -shared -o libpytest.so pytest.o -defaultlib=libphobos2.so 
> -L-rpath=/usr/local/lib
> python
>
>>>> import pytestpy
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> ImportError: /usr/local/lib/libpytest.so: undefined symbol: 
> _D3std5stdio12__ModuleInfoZ
>
>
> I guess it is not linking to the D runtime, but I am not sure 
> what I should be doing to fix.
>
> Any thoughts appreciated.
>
> (The next step I was going to try when this works was C++ 
> interface vs importing as a Cython class, but I thought best to 
> start simple).
>
> I am running this on 64 bit Fedora 20.
>
> Thanks.
>
>
> Laeeth.
Since when does gcc have a -defaultlib option?
---
$ man gcc | grep  defaultlib
object-file-name  -llibrary -nostartfiles  -nodefaultlibs
              This is useful when you use -nostdlib or
-nodefaultlibs but you do
              -nodefaultlibs is used.
          -nodefaultlibs
              -nodefaultlibs is libgcc.a, a library of internal
subroutines which
              -nodefaultlibs you should usually specify -lgcc as
well.  This
---
and why do you have a main function when compiling a shared
library?

Anyway, I think the problem is that "libpytest.so" can't find
"libphobos2.so". Try adding "libphobos2.so"'s location
(/usr/lib/x86_64-linux-gnu/libphobos2.so on my linux mint) to
your -rpath .


More information about the Digitalmars-d-learn mailing list