python - 如何使用 pybind11 将 python 函数保存到静态 c++ 容器?
问题描述
本质上,在 C++ 方面,我有一个容器,其中包含某种类型的函数。现在我想把这个容器暴露给 python,让用户可以提供他们自己的 python 函数。
最简单的示例如下所示:
#include "pybind/common/Common.h"
using CppFunc = std::function< int (int) >;
PYBIND11_MODULE( test, m )
{
m.def("addFunc", [](const pybind11::function& f){
static std::vector<CppFunc> vec{};
vec.push_back(f.cast<CppFunc>());
});
}
然后在python中我想做这样的事情。
import test
def myFunc(number):
return number+1
test.addFunc(myFunc)
有趣的是,这很好用。但是,如果我使用“python script.py”运行脚本,它会运行然后永远不会终止。在交互式控制台中,相同的代码可以正常工作,直到您尝试关闭控制台:进程卡住了。
如何安全地将这个 python 函数存储在 C++ 容器中?
解决方案
static std::vector<CppFunc> vec{}
存储对由于静态存储而永远不会释放的python对象(用户函数)的引用,因此解释器无法终止。
为了确保解释器终止,您可以在模块终止时调用清理函数:
#include "pybind11/pybind11.h"
#include "pybind11/functional.h"
namespace py = pybind11;
using CppFunc = std::function< int (int) >;
PYBIND11_MODULE( test , m )
{
static std::vector<CppFunc> vec{};
m.def("addFunc", [](CppFunc f){
vec.push_back(std::move(f));
});
m.add_object("_cleanup", py::capsule([]{ vec.clear(); }));
}
有关更多详细信息,请参阅文档: https ://pybind11.readthedocs.io/en/stable/advanced/misc.html#module-destructors
推荐阅读
- r - 如何替换特定的向量值?
- heap - 对于使用堆查找前 K 个元素,哪种方法更好 - NlogK 还是 KLogN?
- jenkins - 严重:https://jenkins.domainname.com/tcpSlaveAgentListener/ 似乎正在发布无效的 X-Instance-Identity
- java - 如何从字符串中仅提取数字
- node.js - 使用预签名 url 流式上传到 S3 失败,出现 403
- php - 应用程序 Redis 之间的共享会话
- vb.net - .net 4.7.2 上的 webview2 使用 c# 或 vb - 不是核心
- windows-authentication - Hololens 2:禁用 Windows Hello 要求
- javascript - 为什么文本不在移动设备中居中 (HTML)
- python - Python:不从线性同余生成器函数返回值