简体   繁体   中英

cython wrapping of a templated c++ class gives undefined symbol

This seems like it should be a very simple question, and I've seen similar discussions here, but nothing that quite tackles this problem. I have a class written in c++ that I would like to access with cython. The simple example below illustrates the problem, it compiles just fine, however, I get an ImportError when I use it.

//element.h

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

and

//element.cc

#include  "element.h"

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

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

it's accessed through the following simple 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

and compiled in place with

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)

However, when I try to import the resulting shared library, I get

ImportError: .../example.so: undefined symbol: _ZN7elementIiEC1Ei

If I simply strip out all the templating and force ints for example, the code compiles just fine (as before) but this time it runs. So, in other words, this works fine.

//element.h                                                                                                                                                                                             
class element{
    public:
        element(int);
        ~element();
        int data;
};

and

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

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

element::~element(){
}

and

//example.pyx
cdef extern from "element.h":

    cdef cppclass element:

        element(int) except +
        int data

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

What am I doing wrong with the templating in the first case?

You need to implement template in one header file instead of split into element.cc . When I run c++file command it shows that compiler failed to link element constructor definition

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM