【问题标题】:python function as parameter to c++ exposed class using ::boost::python使用 ::boost::python 将 python 函数作为 c++ 公开类的参数
【发布时间】:2011-11-20 08:43:48
【问题描述】:

我已经将 Python 和 C++ 一起使用了一段时间,但从未尝试过实现以下内容:

我喜欢 python 用户能够编写类似的东西:

def foo(a,b):
    return a+b

myclass.myfunc(foo)

其中 myclass 是使用 Boost.Python 向 python 公开的 c++ 类,其方法之一 (myfunc) 采用以下函数:

int func(int,int)

签名,仅此而已。

这可能吗?

我正在考虑声明:

myclass::myfunc(boost::python::object)

并提取 typedef 的函数签名,但我只是猜测..

也许有更好/可行的方法来做到这一点,也许有一些“功能”对象?

【问题讨论】:

  • 也许更好的标题是“python 函数作为 boost::python c++ 暴露类的参数”
  • 这是一个有趣的问题,我很想知道答案。

标签: c++ python boost-python


【解决方案1】:

你几乎猜到了答案。 Python 函数确实只是 boost::python::object 实例。然后,您可以拥有一个 boost::function<int (int, int)> 并将 Python 对象放入其中。

我刚刚安装了我的操作系统,但我还没有 Boost,所以我无法对其进行测试,但我认为如果你这样做(没有任何包装函数)它会起作用:

void function(boost::function<int (int, int)> func) {
    // ...
}

// And then you expose the function as you normally would

我希望上述方法有效;如果不是,这肯定会:

void function_wrap(boost::python::object func)
{
    auto lambda = [func](int a, int b) -> int {
        return boost::python::extract<int>(func(a, b));
    };
    function(boost::function<int (int, int)>(lambda));
}

// And then you expose the wrapper, not the original function

【讨论】:

  • 这就是我所追求的......我会尽快测试并发布结果,谢谢
  • 有趣。如果func 不是可调用的,::boost::python 会做什么?我认为 ::boost::python::object 有一个 operator () 的模板版本来完成这项工作。
  • @Omnifarious 是的,有一个模板化的operator()。如果对象不可调用,则会抛出异常(我不记得它被调用了什么)——这与您尝试在 Python 中调用不可调用对象时发生的情况几乎相同。
  • 好的.. 所以:第一个不起作用,它(可以预见)抱怨没有转换器从 boost::python::object 获取 boost::function,然后我升级到g++ 4.5(为了使用 lambdas)并且效果很好。现在,你能告诉我具体是怎么回事吗?请原谅我的无知.. 但即使我知道 lambdas 我也无法弄清楚它为什么会起作用.. 最后一行的 function() 是什么?提前感谢
  • @user815129 function 是你原来的函数; function_wrap 是一个帮助函数,可让您的 C++ 代码与 Python 兼容。您的原始函数希望接收一个函数对象,因此您不能将其传递给 int;取而代之的是,您将传递给它的 lambda 将调用 python::object 并将其返回类型转换为 int。
猜你喜欢
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
相关资源
最近更新 更多