未定义的符号错误导入用Cython模块(Undefined symbol error importi

2019-07-01 22:25发布

我想我的C ++类的Python模块可用之一。 这个类是在头宣布Foo.h和一个.cpp实现Foo.cpp 。 (克++ - 4.5,Ubuntu的x86_64的)。 这是一个非常非常简单的类:

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

我创建了一个setup.py如图用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},
)

跟着用Cython教程写我的指令Foo.pyx用Cython模块:

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.so创建共享库的对象,但是当我想从蟒蛇导入它,我得到:

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

我认为这是_ZN4FooD1Ev的构造函数的重整名称Foo ,但不知道如何丢失的符号。

我实在无法理解什么符号从共享对象文件丢失。 而作为第二点,之后python setup.py build_ext --inplace命令,我Foo.cpp的文件被搞砸了 ,并包含cythonized版本。

如何可能重命名为其他格式cythonized文件(例如.cxx ),并避免链接错误?

然后我修改了Foo.pyxpFoo.pyx ,因此修改setup.py ,现在setup命令后,我的cythonized版本pFoo.pyxFoo.cxx但是当我试图导入我得到的

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

有什么不对我的设置,以及如何可以解决我的问题呢?

Answer 1:

我建议您用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
      ))

要定义一个C ++类,使用“cppclass”关键字,如下:

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

然后,您应该能够访问像这样的类:

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


文章来源: Undefined symbol error importing Cython module