Tôi muốn tạo sẵn một trong các lớp C++ của tôi làm mô-đun Python. Lớp được khai báo trong tiêu đề Foo.h
và được triển khai trong một .cpp Foo.cpp
. (g ++ - 4.5, Ubuntu x86_64). Đó là một lớp rất rất đơn giản:Lỗi biểu tượng không xác định nhập khẩu mô-đun 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;
};
Tôi tạo ra một setup.py
như trong Cython hướng dẫn:
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},
)
và theo chỉ dẫn của hướng dẫn cython để viết mô-đun Foo.pyx
cython tôi:
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)
tôi biên dịch nó với lệnh sau: 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
Bây giờ Foo.so
đối tượng thư viện được chia sẻ được tạo nhưng khi tôi muốn nhập nó từ python, tôi nhận được:
>>> import Foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./Foo.so: undefined symbol: _ZN4FooD1Ev
>>>
Tôi nghĩ rằng _ZN4FooD1Ev là tên đọc sai của các nhà xây dựng của Foo
nhưng không hiểu làm thế nào là mất tích biểu tượng.
Tôi thực sự không thể hiểu biểu tượng nào bị thiếu trong tệp đối tượng được chia sẻ. Và là điểm thứ hai, sau lệnh python setup.py build_ext --inplace
, tệp Foo.cpp
của tôi là bị lỗi và chứa phiên bản được mã hoá.
Làm cách nào để đổi tên tệp được mã hóa ở định dạng khác (ví dụ: .cxx
) và tránh lỗi liên kết đó?
sau đó tôi sửa đổi Foo.pyx
trong pFoo.pyx
và do sửa đổi setup.py
, bây giờ sau khi lệnh thiết lập tôi có phiên bản cythonized của pFoo.pyx
trong Foo.cxx
nhưng khi tôi cố gắng nhập tôi nhận được
ImportError: dynamic module does not define init function (initpyFoo)
gì là sai với thiết lập của tôi và làm thế nào có thể để giải quyết vấn đề của tôi?
Lớp Foo có trình tạo bản sao được xác định trong tệp cpp không? –
Không, nó thực sự không có hàm tạo bản sao nào được xác định, khi được định nghĩa và đổi tên thành 'Foo.pyx' trong' pyFoo.pyx' tôi đã giải quyết được vấn đề. – linello