使用Pybind11在C++中向Python函数传递C++函数报错问题
问题:C11调用Python函数时传递C函数报错
我需要在C11代码中调用Python的eval函数,并将C定义的函数作为参数传入,相关代码如下:
Python代码(my_module.py)
def eval(foo): return foo(1)
C++代码(main.cpp)
#include <iostream> #include <vector> #include <pybind11/embed.h> #include <pybind11/numpy.h> namespace py = pybind11; double foo (double x) { return x; }; auto foo_py = py::vectorize(foo); int main() { py::scoped_interpreter guard{}; py::module m = py::module::import("my_module"); m.attr("eval")(foo_py); }
运行时错误:
terminate called after throwing an instance of 'pybind11::cast_error'
what(): 无法将类型为'detail::vectorize_helper (*)(double), double, double>'的调用参数'0'转换为Python对象
解决方法
问题根源是py::vectorize返回的是C++侧的辅助类型,无法直接被pybind11自动转换为Python可调用对象,需要显式处理:
方法1:用py::cpp_function包装函数
如果不需要向量化处理数组,直接把C++函数包装成Python可调用对象即可:
// 替换原代码中的auto foo_py = py::vectorize(foo); py::cpp_function foo_py(foo);
若确实需要向量化功能,可将py::vectorize的结果包装进py::cpp_function:
auto vec_foo = py::vectorize(foo); py::cpp_function foo_py([vec_foo](double x) { return vec_foo(x); });
方法2:显式转换为Python对象
在传递参数时用py::cast将foo_py转为Python可识别的对象:
m.attr("eval")(py::cast(foo_py));
内容的提问来源于stack exchange,提问作者Coeus
相关产品推荐
相关产品推荐

