带有C ++模板的SWIG:未定义的符号

时间:2011-03-06 22:44:03

标签: c++ python swig

C ++模板和SWIG对我来说并不是很好。

当我尝试导入模块时,我收到错误

ImportError: ./_simple.so: undefined symbol: _Z9double_itIiET_S0_

我正在使用SWIG 1.3。

以下是一个显示问题的简单示例:

//file: simple.h
template <typename T>
T double_it (T a);

//file: simple.cc
template <typename T>
T double_it (T a) {
  return (2 * a);
}

//file: simple.i
%module "simple"

%{
  #include "simple.h"
%}

%include "simple.h"

%template(int_double_it) double_it <int>;
%template(float_double_it) double_it <float>;

#file: setup.py
from distutils.core import setup, Extension
simple_module = Extension('_simple',
                          sources=['simple.i', 'simple.cc'],
                          swig_opts=['-c++'],
                          )
setup (name = 'simple',
       ext_modules = [simple_module],
       py_modules = ["simple"],
       )

然后用:

建立
python setup.py build

如果我将simple.cc的内容包含到simple.i中并从setup.py中删除对simple.cc的引用,那么一切正常,但当事情变得更复杂时,这不是真正的解决方案。

接下来,我将给出一个类似但不使用模板并且工作正常的反例。

//file: simple.h
int double_it (int a);

//file: simple.cc
int double_it (int a) {
  return (2 * a);
}

//file: simple.i
//Same as before but with %template statements removed.
%module "simple"

%{
  #include "simple.h"
%}

%include "simple.h"

#file: setup.py
#Identical to previous example.

1 个答案:

答案 0 :(得分:3)

通常,模板是在头文件中定义的,而不是在cc文件中定义的。使用您的设置,编译器无法找到/编译模板的实现。

您需要更改代码的组织,以便模板实现可用:

//file: simple.hh
template <typename T>
T double_it (T a) {
  return (2 * a);
}

//file: simple.i
%module "simple"

%{
  #include "simple.hh"
%}

%include "simple.hh" // include it directly into here

%template(int_double_it) double_it <int>;
%template(float_double_it) double_it <float>;

#file: setup.py
from distutils.core import setup, Extension
simple_module = Extension('_simple',
                          sources=['simple.i', 'simple.hh'],
                          swig_opts=['-c++'],
                         )
setup (name = 'simple',
       ext_modules = [simple_module],
       py_modules = ["simple"],
       )

我很欣赏您的示例已经过简化,但它说明了这一点。您不必直接%include实现(但您需要#include它),但您必须向SWIG编译器提供某些实现,即使它是一个简化版本。

以上内容应该让你前进。