如果我在不同的 pybind11::scoped_interpreter 会话中两次导入外部模块,则应用程序在函数 eval 中的 eval.h 中崩溃,如下行:
PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
和
Exception thrown at 0x00007FFD710C4E0C (multiarray.cp36-win_amd64.pyd) in pybind-test.exe: 0xC0000005: Access violation writing location 0x000000000000000A.
可重现的示例代码
namespace py = pybind11;
void test() {
try {
py::scoped_interpreter guard{};
py::object mainScope = py::module::import("__main__").attr("__dict__");
py::exec(
"import numpy\n",
mainScope);
}
catch (py::error_already_set const &pythonErr) { std::cout << pythonErr.what(); }
}
int main() {
test(); // Runs fine
test(); // Crashes at py::exec
}
我觉得这与 pybind11 的 embed.h 中的评论有关:
可以通过再次调用来重新启动解释器
initialize_interpreter
。使用 pybind11 创建的模块可以安全地重新初始化。但是,Python 本身不能完全卸载二进制扩展模块,并且在解释器重启方面有几个注意事项。所有详细信息都可以在 CPython 文档中找到。简而言之,由于引用循环或用户创建的全局数据,并非所有解释器内存都可以释放。
那么有没有办法两次调用Python解释器呢?我有一个 python 文件,其中包含我需要在 C++ 算法执行的不同点调用的辅助 numpy 函数。这是否意味着我不能这样做?