如果我在不同的pybind11::scoped_interpreter会话中两次导入外部模块,应用程序将在eval.h的eval函数中崩溃,位于以下行:
我觉得这与pybind11的embed.h中的注释有关:
引用: 解释器可以通过再次调用
那么,这就意味着不能调用Python解释器两次吗?我有一个包含帮助numpy函数的Python文件,我需要从C++中的算法执行的不同点调用它。这是否意味着我不能这样做?
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解释器两次吗?我有一个包含帮助numpy函数的Python文件,我需要从C++中的算法执行的不同点调用它。这是否意味着我不能这样做?
test()
应该在自己的作用域内(即将{}
放在它周围),否则解释器会在 test 中的所有内容完成之前被解构(至少他们有一个例子,在那里他们读回了一个返回值,但在解释器之后被解构)。 - Florian Blume