python - 导入 Cython 模块时出现 undefined symbol 错误

标签 python cython distutils undefined-reference

我想将我的一个 C++ 类作为 Python 模块提供。该类在 header Foo.h 中声明,并在 .cpp Foo.cpp 中实现。 (g++-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 共享库对象,但是当我想从 python 导入它时,我得到:

 >>> 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版本。

如何以另一种格式(例如 .cxx)重命名 cythonized 文件并避免该链接器错误?

然后我修改了 pFoo.pyx 中的 Foo.pyx 并因此修改了 setup.py,现在在设置命令之后我有Foo.cxxpFoo.pyx 的 cythonized 版本,但是当我尝试导入时,我得到了

ImportError: 动态模块没有定义初始化函数 (initpyFoo)

我的设置有什么问题以及如何解决我的问题?

最佳答案

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

关于python - 导入 Cython 模块时出现 undefined symbol 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13026523/

相关文章:

python - 为什么 pip 尝试安装 ctypes?

python - 当不满足条件时中断 if __name__

python - 如何继承Django变量?

python - 如何在 cython 中使用 unordered_map?

python setup.py develop 覆盖已安装的版本

python - 安装工具/distutils : Installing files into the distribution's DLLs directory on Windows

python - 从linux中的 Pandas 数据框列中减去日期

python pandas DataFrame 遍历行并比较两列并应用函数

python - 使用 cython 加速 numpy 数组的类(class)速度

python - 可以使用 while(file >> ...) C++ 习惯用法来读取 Cython 中的文件吗?