如何使用SWIG为C ++模板类

时间:2015-10-13 14:33:14

标签: python c++ templates swig

我们正在尝试使用SWIG为不同的语言包装C ++模板库(Python,Java,R ..)。我们不希望在traget语言中为每个类型实例化使用不同的类名。相反,我们想要一个调度类(就像SWIG处理重载函数一样)。由于我们有很多类,我们还希望让SWIG从给定的C ++头文件中提取类和方法。

示例:假设包含

的c ++标头(只读)
template< typename T >
class Foo {
    Foo(const T * t);
    const T* getVal() const;
    void setVal(const T* t);
};

现在我们要为SWIG编写一个接口文件,它创建一个单个类,该类调度到正确的模板实例化(如果在每次函数调用中都发生这种情况就没问题)。在Python中我们想要允许这样的东西

from foo import Foo
v_int = Foo(1)
v_int.setVal(v_int.getVal())
v_str = Foo("string")
v_str.setVal(v_str.getVal())

我有一些想法如何手动执行此操作,但它基本上意味着我必须在C ++中编写自己的包装类,其中包含模板类定义的每个成员函数。我们希望将大量的类包装成一个不切实际的解决方案。

有什么想法吗?例如。有没有办法“迭代”SWIG接口文件中的所有成员函数?

1 个答案:

答案 0 :(得分:0)

我自己没有对此进行测试,但SWIG documentation on C++ template似乎表明这相当容易,您只需要告诉SWIG您希望模板接受哪些类。将示例调整到示例标题,您的SWIG文件将类似于:

%module foo
%{
#include "foo.h"
%}

template< typename T>
class Foo {
    Foo(const T *t);
    const T* getVal() const;
    void setVal(const T* t);
};

%template(i) foo<int>;
%template(str) foo<string>;
对于要与模板一起使用的任何其他类型,

加上类似的行。

然后你可以在python中使用它:

>>> v_int = Foo.i(1)
>>> v_int.setVal(v_int.getVal())
>>> v_str = Foo.str("string")
>>> v_str.setVal(v_str.getVal())

现在,我知道你说你不想为每个实例化使用不同的类名,因为在这里你必须决定创建对象的类型,而不是你得到的完全透明的模板用法在本机C ++中。但它似乎相当接近,而且远比为一切编写包装类少得多。