我们正在尝试使用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接口文件中的所有成员函数?
答案 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 ++中。但它似乎相当接近,而且远比为一切编写包装类少得多。