繁体   English   中英

使用SWIG作为具有输入参数功能的函数

[英]Using SWIG for functions with functions as input parameter

考虑以下最小的例子:我有一个C ++函数'myfun',它接受一个数字和另一个函数作为输入,并返回在x处计算的函数:

双myfun(双x,双(* f)(双y))
{return f(x); }

我将此代码存储在'test.cpp'中。 相应头文件'test.hpp'中的代码很简单

double myfun(double x,double(* f)(double y));

现在,我尝试使用SWIG从Python访问'myfun'。 'swig.i'文件如下所示:

%模块测试
%{
#include“test.hpp”
%}
double myfun(double x,double(* f)(double y));

每当我尝试在Python中调用此函数时,例如使用

从测试导入myfun
myfun(2,lambda y:y ** 2)

我收到错误:

在方法'myfun'中,参数2'double(*)(double)'

所以我的问题很简单:如何修改'swig.i'文件,以便我可以将任何(合适的Python)函数传递给'myfun'? (这个问题与这篇文章有点相关如何包装一个c ++函数,它使用SWIG接收python中的函数指针 '但不同之处在于我在C ++中没有指定输入函数,而是我想保持它为一个免费的“参数”)。

在编写绑定时回调需要额外的处理,这在SWIG中尚未得到支持,显然没有真正的解决方法。

重点是SWIG是关于从Python(和其他语言)调用C,而不是从C调用Python。

我们使用的是SIP ,它是一个更复杂的绑定生成器(不过是C ++ / Python特有的)。 SIP支持回调甚至从C ++类继承Python类。

该工具非常强大,是PyQt绑定的引擎。

但请注意,Python中的可调用函数不仅仅是C ++中的函数,因为它可以包含上下文(它可以是闭包)。 在C ++代码中:

int callF(int (*f)(int, int), int a, int b) {
    return f(a, b);
}

只能调用一个纯无上下文的函数,所以传递一般的Python回调是不可能的,因为没有足够的信息(唯一的解决方案是分配预编译的trampolines或在运行时生成C ++代码)。

如果你可以控制双方,但是解决方法是创建一个包含回调的C类并在Python中派生它。 例如:

struct CBack {
    virtual int operator()(int x, int y) const {
        return x+y;
    }
    virtual ~CBack() {}
};

int callF(const CBack& f,
          int xv, int yv)
{
    return f(xv, yv);
}

然后从CBack派生一个Python类并传递:

class Add(CBack):
    def __call__(self, x, y):
        return x + y

class Mul(CBack):
    def __call__(self, x, y):
        return x * y

print callF(Add(), 3, 7) # will print 10
print callF(Mul(), 3, 7) # will print 21

在这种情况下,你也可以传递一个(包裹的)lambda

def cback(f):
    class PyCBack(CBack):
        def __call__(self, x, y):
            return f(x, y)
    return PyCBack()

print callF(cback(lambda x, y: x*y), 3, 7)

换句话说,一个阻抗问题是C ++的函数与Python的函数不同(Python的函数也可以有上下文)。

可以从这里下载完整的示例。

根据文件 (强调我的):

尽管SWIG通常不允许以目标语言编写回调函数 ,但这可以通过使用类型映射和其他高级SWIG功能来实现。

如果您想深入了解该主题, 是建议的章节。
无论如何,它看起来不是该工具的预期关键功能。
您可以做的最好的事情是获得一个围绕Python设计的解决方案,并且不能与其他目标语言一起使用,但它通常不是Swig的用户想要的。

请注意,您仍然可以在C / C ++中编写回调并将它们作为常量导出,然后从目标语言中使用它们。
有关详细信息,请参阅上面的文档。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM