2012-10-23 2 views
8

내 C++ 클래스 중 하나를 Python 모듈로 사용하려고합니다. 클래스는 헤더 Foo.h에 선언되고 .cpp Foo.cpp으로 구현됩니다. (g ++ - 4.5, 우분투 x86_64).Cython 모듈 가져 오기에서 정의되지 않은 기호 오류가 발생했습니다.

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 : 사이 썬 튜토리얼과 같이
class Foo 
{ 
public: 

    Foo() 
    Foo(const Foo& orig); 
    ~Foo(); 
    double alfa; 
    int beta; 
}; 

가 나는 setup.py을 만들어 :

Foo.cpp :

Foo::Foo() : alfa(1.0), beta(1) 
{ 

} 

Foo::~Foo() 
{ 
} 

Foo.h 그것은 매우 매우 간단한 클래스입니다 나는 다음과 같은 명령으로 컴파일

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 사이 썬 모듈을 작성하는 사이 썬 튜토리얼의 지시에 따라 공유 라이브러리 객체가 생성되었지만 파이썬에서 가져 오기를 원할 때 얻을 수 있습니다.

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

나는 _ZN4FooD1EvFoo의 생성자의 변환 된 이름이지만 기호 누락하는 방법을 이해하지 못하고 있다고 생각합니다.

공유 객체 파일에서 어떤 기호가 누락되었는지 정말 이해할 수 없습니다. 두 번째로 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 모듈에 다른 이름을 사용하는 것이 좋습니다.

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

하는 당신은 다음과 같이 클래스에 액세스 할 수 있어야합니다 : 아래와 같이 'cppclass'키워드를 사용

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

는 C++ 클래스를 정의하려면 : cFoo는 이름 충돌 문제를 방지하려면 :

cdef Foo *foo = new Foo() 
foo.beta = 42