Cython包装一个模板化的C++类出现了未定义符号

3

这似乎是一个非常简单的问题,我在这里看到了类似的讨论,但没有完全解决这个问题的内容。我有一个用c++编写的类,我想用cython来访问它。下面的简单示例说明了问题,它可以编译,但使用时我会收到ImportError错误。

//element.h

template <typename T>
class element{
    public:
        element(T);
        ~element();
        T data;
};

并且

//element.cc

#include  "element.h"

template <typename T>
element<T>::element(T _data){
    data = _data;
}

template <typename T>
    element<T>::~element(){
}

它通过以下简单的Cython进行访问

cdef extern from "element.h":
    cdef cppclass element[T]:
        element(T) except +
        T data

cdef element[int] *el = new element[int](3)
print el.data

并在现场编译

from distutils.core import setup, Extension
from Cython.Distutils import build_ext

ext_modules = [Extension("example",
               ['example.pyx','./element.cc'],
               language = "c++")]

setup(cmdclass = {'build_ext':build_ext},
    name = 'example',
    ext_modules = ext_modules)

然而,当我尝试导入生成的共享库时,遇到了问题。
ImportError: .../example.so: undefined symbol: _ZN7elementIiEC1Ei

如果我只是简单地去掉所有的模板并强制将整数转换为例子中的类型,那么代码将会编译成功(与之前一样),但这一次它可以运行。因此,换句话说,这个方法可以很好地解决问题。
//element.h                                                                                                                                                                                             
class element{
    public:
        element(int);
        ~element();
        int data;
};

并且

//element.cc
#include  "element.h"

element::element(int _data){
    data = _data;
}

element::~element(){
}

并且。
//example.pyx
cdef extern from "element.h":

    cdef cppclass element:

        element(int) except +
        int data

cdef element *el = new element(3)
print el.data

在第一种情况下,我使用的模板有什么问题吗?
1个回答

2

你需要将模板实现在一个头文件中,而不是分开到element.cc中。当我运行c++file命令时,显示编译器无法链接元素构造函数的定义。

$ c++filt _ZN7elementIiEC1Ei
element<int>::element(int)

啊,当然 - 这与 Cython 没有任何关系,一切都与正确使用模板有关。非常感谢! - peterH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接