3

これは非常に単純な質問のように思えます。ここで同様の議論を見てきましたが、この問題に完全に取り組むものは何もありません。cython でアクセスしたい c++ で書かれたクラスがあります。以下の簡単な例は問題を示しています。問題なくコンパイルされますが、使用すると 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

たとえば、すべてのテンプレートと強制 int を単純に削除すると、コードは (以前と同様に) 正常にコンパイルされますが、今回は実行されます。つまり、言い換えれば、これはうまく機能します。

//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

最初のケースのテンプレートで何が間違っていますか?

4

1 に答える 1

2

に分割するのではなく、1 つのヘッダー ファイルにテンプレートを実装する必要がありますelement.cc。コマンドを実行するc++fileと、コンパイラが要素コンストラクター定義のリンクに失敗したことが示されます

$ c++filt _ZN7elementIiEC1Ei
element<int>::element(int)
于 2013-08-11T06:41:45.307 に答える