2012-10-23 18 views
8

私のC++クラスをPythonモジュールとして利用したいと思います。クラスはヘッダFoo.hで宣言され、.cpp Foo.cppで実装されています。 (g ++ - 4.5、Ubuntu x86_64)。それは非常に非常に単純なクラスです:Cythonモジュールをインポートする際にシンボルが定義されていません。

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

Cythonのチュートリアルに示すように、私はsetup.pyを作成しました:

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}, 
) 
0私は、次のコマンドでコンパイルし

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) 

:今 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 

とは、私のFoo.pyx cythonモジュールを書くことcythonのチュートリアルの指示に従っ共有ライブラリオブジェクトが作成されますが、Pythonからインポートする場合は、次のようになります。

>>> import Foo 
     Traceback (most recent call last): 
     File "<stdin>", line 1, in <module> 
     ImportError: ./Foo.so: undefined symbol: _ZN4FooD1Ev 
>>> 

私は_ZN4FooD1EvFooのコンストラクタのマングルされた名前であると思いますが、シンボルが欠落しているかを理解していません。

私は本当に共有オブジェクトファイルからどのシンボルが欠落しているのか理解できません。 そして、第2のポイントとして、python setup.py build_ext --inplaceコマンドの後、私のFoo.cppファイルはであり、が台無しにされ、cythonizedバージョンが含まれています。

cythonizedファイルの名前を別の形式(たとえば.cxx)に変更し、そのリンカーエラーを回避するにはどうすればよいですか?

私はその後pFoo.pyxFoo.pyxを修正し、その結果setup.pyを変更し、今セットアップコマンドの後に私はFoo.cxxpFoo.pyxのcythonizedバージョンを持っているが、私はインポートしようとすると、私は

ImportError: dynamic module does not define init function (initpyFoo)

何を得ます私のセットアップに間違っていると私の問題を解決する方法は可能ですか?

+0

Fooクラスのコピーコンストラクタがcppファイルで定義されていますか? –

+0

いいえ、実際には定義されていないコピーコンストラクタが定義されていて、 'pyFoo.pyx'の' Foo.pyx'の名前が変更されました。私はこの問題を解決しました。 – linello

答えて

2

あなたのcythonモジュールに別の名前を使用することをお勧めします。名前の衝突の問題を回避するためにcFoo、:

from distutils.core import setup 
from Cython.Build import cythonize 

setup(ext_modules = cythonize(
      "cFoo.pyx",     # our Cython source 
      sources=["Foo.cpp"],  # additional source file(s) 
      language="c++",    # generate C++ code 
    )) 

以下のように、「cppclass」キーワードを使用し、C++クラスを定義するには:あなたはそのようにのようなあなたのクラスにアクセスすることができるはず

cdef extern from "Foo.h": 
    cdef cppclass Foo: 
     Foo() 
     double alfa 
     int beta 

cdef Foo *foo = new Foo() 
foo.beta = 42 
関連する問題