首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以函数作为输入参数的函数使用SWIG

以函数作为输入参数的函数使用SWIG
EN

Stack Overflow用户
提问于 2016-11-11 06:13:29
回答 2查看 777关注 0票数 3

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

双倍(双x,双(*f)(双y)) {返回f(x);}

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

双倍(双x,双(*f)(双y));

现在,我尝试使用SWIG来访问Python中的“我的乐趣”。“swg.i”文件如下所示:

%模块测试 %{ #包括"test.hpp“ %} 双倍(双x,双(*f)(双y));

每当我试图在Python中调用这个函数时,例如

从测试进口我的 我的乐趣(2,lambda y: y**2)

我收到错误:

在方法“myfun”中,类型为“double(*)(Double)”的参数2

因此,我的问题很简单:如何修改‘swg.i’文件,以便我可以将任何(合适的Python)函数传递给'myfun'?(这个问题在某种程度上与这个post 如何使用SWIG包装c++函数,该函数在python中接受函数指针‘有关,但区别在于这里我没有在C++中指定输入函数,而是希望将它保留为一个自由的’参数‘)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-11 07:02:26

在编写绑定时,回调需要额外的处理,而且这在SWIG中还不支持,而且显然没有真正的解决办法。

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

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

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

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

代码语言:javascript
复制
int callF(int (*f)(int, int), int a, int b) {
    return f(a, b);
}

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

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

代码语言:javascript
复制
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类并传递:

代码语言:javascript
复制
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。

代码语言:javascript
复制
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的函数也可以具有上下文)。

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

票数 3
EN

Stack Overflow用户

发布于 2016-11-11 06:45:44

根据文档 (强调地雷):

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

是建议的章节,如果您想深入讨论这个主题的话。

无论如何,它看起来似乎不是该工具的一个预期的关键特性。

您所能做的最好的就是获得一个围绕Python设计的解决方案,它不会与其他目标语言一起工作,但这通常不是Swig的用户想要的。

请注意,您仍然可以用C/C++编写回调,并将它们作为常量导出,然后从目标语言中使用它们。

有关更多细节,请参阅上述我的文档。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40542159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档