避免pybind11生命周期问题

时间:2019-11-01 16:33:10

标签: python c++ pybind11

我正在用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的社区分享任何结果。

0 个答案:

没有答案