1

我一辈子都无法在使用 pybind11 构建的扩展模块中获得一个非常基本的 Python 回调函数。我试图按照这里的例子,但我想我一定是误解了一些东西。

C++代码如下:

#include <iostream>
#include <functional>
#include <pybind11/pybind11.h>

namespace py = pybind11;

void run_test(const std::function<int(int)>& f)
{
   // Call python function?
   int r = f(5);
   std::cout << "result: " << r << std::endl;
}

PYBIND11_PLUGIN(mymodule)
{
    py::module m("mymodule");
    m.def("run_test", &run_test);
    return m.ptr();
} 

使用这个模块的 Python 代码是

import mymodule as mm

# Test function
def test(x):
  return 2*x

mm.run_test(test)

但是我收到此错误:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    mm.run_test(test)
TypeError: run_test(): incompatible function arguments. The following argument types are supported:
    1. (arg0: std::function<int (int)>) -> None

Invoked with: <function test at 0x2b506b282c80>

为什么它认为函数签名不匹配?我试图匹配这些例子,但我想我一定误解了一些东西......

4

2 回答 2

0

啊,好吧,我误解了为什么在那个例子中使用了 std::function 。这是一个更复杂的双重回调,其中一个 C++ 函数被传递给 Python,然后返回到 C++,以检查它是否在整个过程中幸存下来。对于仅调用 Python 函数,需要使用py::object并将结果转换为 C++ 类型(如此所述):

void run_test(const py::object& f)
{
   // Call python function?
   py::object pyr = f(5);
   int r = pyr.cast<int>();
   std::cout << "result: " << r << std::endl;
}
于 2017-11-24T14:16:56.007 回答
0

我相信你的问题是你忘了#include <pybind11/functional.h>

于 2018-12-03T19:45:13.350 回答