gpt4 book ai didi

python - 将 SWIG 用于以函数作为输入参数的函数

转载 作者:太空狗 更新时间:2023-10-29 22:58:27 32 4
gpt4 key购买 nike

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

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

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

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

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

%module test
%{
#include "test.hpp"
%}
double myfun(double x, double (*f)(double y));

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

from test import myfun
myfun(2, lambda y: y**2)

我收到错误:

in method 'myfun', argument 2 of type 'double (*)(double)'

所以我的问题很简单:如何修改“swig.i”文件,以便我可以将任何(合适的 Python)函数传递给“myfun”? (这个问题与这篇文章 How to wrap a c++ function which takes in a function pointer in python using SWIG 有点相关,但不同的是,这里我没有在 C++ 中指定输入函数,而是我想将它保留为一个自由的“参数”)。

最佳答案

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

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

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

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

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

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

只能调用纯上下文无关函数,因此不可能向它传递一个通用的 Python 回调,因为没有足够的信息(唯一的解决方案是分配预编译的蹦床或在运行时生成 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 的函数也可以有上下文)。

可以从 here 下载完整示例.

关于python - 将 SWIG 用于以函数作为输入参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40542159/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com