开发者

SWIG with C++ templates: undefined symbol

C++ Templates and SWIG aren't playing nicely together for me.

When I try to import my module I get the开发者_开发技巧 error

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

I am using SWIG 1.3.

Here is a simple example showing the problem:

//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"],
       )

Then build in with:

python setup.py build

If I include the contents of simple.cc into simple.i and remove the reference to simple.cc from the setup.py then everything works fine, but that isn't really a solution when things get more complex.

Next I'll give a counter example of something that is similar but doesn't use templates and works fine.

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


Typically templates are defined in a header file instead of in a cc file. With the setup you have, the compiler cannot find / compile the implementation of the template.

You will need to change the organization of the code so that the template implementation is available:

//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"],
       )

I appreciate that your example is simplified, but it illustrates the point. You do not have to %include the implementation directly (but you do need to #include it), but you do have to provide some implementation to the SWIG compiler, even if it is a simplified version.

The above should get you going.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜