如何使用SWIG创建C++模板类的调度包装类

2024-04-20 02:45:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我们试图使用SWIG来封装不同语言(Python、java、R.)的C++模板库。我们不希望在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++中编写自己的包装类,其中每个成员函数都在模板类中定义。对于我们想要包装的大量类来说,这是一个不切实际的解决方案。你知道吗

你知道吗?E、 有没有一种方法可以“迭代”SWIG接口文件中的所有成员函数?你知道吗


Tags: 文件实例方法函数模板语言foo成员
1条回答
网友
1楼 · 发布于 2024-04-20 02:45:23

我自己还没有测试过,但是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++中使用的完全透明的模板用法。但它似乎相当接近,而且比为所有内容编写包装器类的工作量要少得多。你知道吗

相关问题 更多 >