使用 pybind11 通过预先存在的嵌入式 python 解释器公开 C++ 功能

Posted

技术标签:

【中文标题】使用 pybind11 通过预先存在的嵌入式 python 解释器公开 C++ 功能【英文标题】:Using pybind11 to expose C++ functionality with preexisting embedded python interpreter 【发布时间】:2020-09-07 11:44:59 【问题描述】:

我是第一次尝试这种类型的编码,因此请原谅我缺乏知识。

要求:我有一个 C++ 代码,其中嵌入了 python 解释器,以便我可以使用 pybind11 导入/使用带有 C++ 的 python 库。此外,我想对这个完整的 C++ 代码(以及 python 解释器部分)进行包装,并将其作为模块公开给 python。为了清楚起见,请考虑以下示例:

**Main_code.cpp:**

    #include <iostream>
    #include <pybind11/embed.h> // everything needed for embedding
    
    int main() 
        pybind11::scoped_interpreter guard; // start the interpreter and keep it alive
        pybind11::module sys = pybind11::module::import("sys");
        pybind11::print(sys.attr("path"));
        return 0;
    

我想将此代码公开给 python(比如作为一个名为 Cpp_func 的模块)并使用“import Cpp_func”在 py 脚本中导入

到目前为止我已经尝试过: 使用 pybind11,我可以设法扩展一个示例 cpp 代码,而无需将 python 解释器嵌入到 python 中。示例取自 pybind11 文档https://pybind11.readthedocs.io/en/latest/basics.html“为简单函数创建绑定”部分。但是当 python 解释器已经嵌入到 C++ 代码中时,我无法弄清楚如何做同样的事情。

希望我的要求很明确。任何关于这方面的 cmet 都会非常有帮助!

提前致谢!

【问题讨论】:

【参考方案1】:

scoped_interpreter_guard 只是 RAII wrapper 周围的 initialize_interpreterfinalize_interpreter。你可以自己打电话给finalize_interpreter,而不是Py_Finalize

【讨论】:

感谢您的回复。但我不明白这将如何帮助实现我的要求。你能提供更多细节吗? @Botje 为什么现在不能创建绑定?出了什么问题?您必须使用PYBIND11_MODULE 宏定义一个新模块,并用定义填充其内容。当你import Python 中的相应模块时,初始化代码将运行,你应该能够访问模块的内容。 这不是问题的答案。 您不应该尝试(重新)在函数中初始化解释器。您只需要在程序结束时调用 finalize_interpreter 即可。

以上是关于使用 pybind11 通过预先存在的嵌入式 python 解释器公开 C++ 功能的主要内容,如果未能解决你的问题,请参考以下文章

返回多个 py::array 而不在 pybind11 中复制

通过使用 pybind11 的虚函数通过引用传递 std::vector 的问题

等效于 pybind11 中的 boost::python py::scope().attr()

pybind11 保持对象活着

pybind11:将 MPI 通信器从 Python 发送到 CPP

Cmake:使用柯南 pybind11 包