我正在用Python编写ReST api请求。这些请求使用pybind11从C ++(Qt)调用并传递到C ++(Qt)。所需的功能按预期执行,但是多次执行脚本时收到以下警告:
context.c:55: warning: mpd_setminalloc: ignoring request to set MPD_MINALLOC a second time
我能够将警告的范围缩小到python requests
包的导入,这是在脚本中调用的。
这是从C ++来看脚本执行的最小示例:
// member of MyWidget
void callMyPythonScript()
{
py::scoped_interpreter guard{};
py::module sys = py::module::import("sys");
auto locals = py::dict("my_scripts"_a="/path/to/my/python-scripts");
py::exec(R"(
import sys
sys.path.insert(0, '{my_scripts}'.format(**locals()))
)", py::globals(), locals);
py::module my_script = py::module::import("my_script");
}
my_script.py
的内容是这样的:
import requests
callMyPythonScript
使用Qt信号槽体系结构连接到C ++一侧的按钮按下:
connect(button_, &QPushButton::clicked,
this, &MyWidget::callPythonCode);
除requests
之外,其他任何软件包都没有收到警告。
经过pybind11 docs,我可能已经对所有这些答案了:
用pybind11创建的模块可以在重新启动解释器后安全地重新初始化。但是,这可能不适用于第三方扩展模块。问题在于Python本身无法完全卸载扩展模块,并且在重新启动解释器方面存在一些警告。简而言之,由于Python参考周期或用户创建的全局数据,并非所有内存都可以释放。
不过,我一直在寻找建立前面提到的体系结构而不必担心内存问题的方法。有人可以建议一个工作流程来解决此问题吗?也许是基于CPython的子解释器实现?
编辑:沿着@jdehesa的评论,我一直在检查Python的C Api。我通常给人的印象是,我可以用它解决我的问题。但是正如网络上许多其他资源所声称的那样,与pybind11相比,这种方法似乎完全是驯服的野兽。甚至pybind11文档都指出,混合使用C Api功能时应格外小心。
就目前而言,我打算完全放弃对Python的请求处理,并将各自的功能移回C ++。
万一有人想提供支持,请随时与我们联系。我仍然对解决方案感到好奇,并将与SO的社区分享任何结果。