Ich möchte eine meiner C++ - Klassen als Python-Modul zur Verfügung stellen. Die Klasse wird in einem Header Foo.h
deklariert und in einer .cpp Foo.cpp
implementiert. (g ++ - 4.5, Ubuntu x86_64). Es ist ein sehr, sehr einfache Klasse:Undefined Symbol Fehler beim Importieren von Cython-Modul
Foo.cpp
:
Foo::Foo() : alfa(1.0), beta(1)
{
}
Foo::~Foo()
{
}
Foo.h
:
class Foo
{
public:
Foo()
Foo(const Foo& orig);
~Foo();
double alfa;
int beta;
};
habe ich eine setup.py
wie in Cython Tutorial gezeigt:
setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
name = 'MyDemo',
ext_modules=[
Extension("Foo"
sources=["Foo.pyx"],
include_dirs=[".","../eigen/"],
language="c++"),
],
cmdclass = {'build_ext': build_ext},
)
und folgte der Anweisung des cython Tutorial mein Foo.pyx
cython Modul zu schreiben:
Foo.pyx
cdef extern from "Foo.h":
ctypedef struct c_Foo "Foo":
double alfa
c_Foo *new_Foo "new Foo"()
void del_Foo "delete" (c_Foo *myfoo)
cdef class Foo:
cdef c_Foo *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self):
self.thisptr = new_Foo()
def __dealloc__(self):
del_Foo(self.thisptr)
ich es mit dem folgenden Befehl kompilieren: python setup.py build_ext --inplace
running build_ext
skipping 'Foo.cpp' Cython extension (up-to-date)
building 'Foo extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I. -I../eigen/ -I/usr/include/python2.6 -c Foo.cpp -o build/temp.linux-x86_64-2.6/Foo.o
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/Foo.o -o /home/linello/prova/Foo.so
Nun ist die Foo.so
Shared Library-Objekt wird erstellt, aber wenn ich es aus Python importieren möchte, bekomme ich:
>>> import Foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./Foo.so: undefined symbol: _ZN4FooD1Ev
>>>
Ich denke, dass _ZN4FooD1Ev der verstümmelten Name des Konstrukteurs von Foo
ist aber nicht verstehen, wie das Symbol fehlt.
Ich kann wirklich nicht verstehen, welches Symbol aus der gemeinsamen Objektdatei fehlt. Und als zweiter Punkt, nach dem python setup.py build_ext --inplace
Befehl, meine Foo.cpp
Datei ist vermasselt und enthält die Cythonized-Version.
Wie ist es möglich, die cythonisierte Datei in einem anderen Format (zum Beispiel .cxx
) umzubenennen und diesen Linkerfehler zu vermeiden?
I modifiziert dann die Foo.pyx
in pFoo.pyx
und verändert damit die setup.py
, jetzt nach dem Setup-Befehl ich die cythonized Version von pFoo.pyx
in Foo.cxx
haben, aber wenn ich versuche ich die
ImportError: dynamic module does not define init function (initpyFoo)
erhalten zu importieren Was ist falsch mit meinem Setup und wie ist es möglich, meine Probleme zu lösen?
Ist der Kopierkonstruktor der Foo-Klasse in der cpp-Datei definiert? –
Nein, es hat eigentlich keinen Kopierkonstruktor definiert, als ich den Namen 'Foo.pyx' in' pyFoo.pyx' definiert und umbenannt habe, habe ich das Problem gelöst. – linello