如何通过 Boost.Python 从 python 文件中导入函数

Posted

技术标签:

【中文标题】如何通过 Boost.Python 从 python 文件中导入函数【英文标题】:How to import a function from python file by Boost.Python 【发布时间】:2016-07-27 18:01:09 【问题描述】:

我对 boost.python 完全陌生。 我查看了很多使用 boost.python 来应用 python 的推荐,但是仍然不容易理解并为我找到解决方案。

我想要的是直接从python“SourceFile”导入一个函数或类

示例文件: 主文件 MyPythonClass.py

假设“MyPythonClass.py”中有一个带有“bark()”函数的“Dog”类,我如何在cpp中获取回调和发送参数?

我不知道该怎么办! 请帮帮我!

【问题讨论】:

【参考方案1】:

如果需要从 C++ 调用 Python,而 C++ 拥有 main 函数,则必须在 C++ 程序中嵌入 Python 中断器。 Boost.Python API 不是 Python/C API 的完整包装,因此可能需要直接调用 Python/C API 的一部分。尽管如此,Boost.Python 的 API 可以使互操作性更容易。考虑阅读官方 Boost.Python embedding tutorial 了解更多信息。


这是一个嵌入 Python 的 C++ 程序的基本框架:

int main()

  // Initialize Python.
  Py_Initialize();

  namespace python = boost::python;
  try
  
    ... Boost.Python calls ...
  
  catch (const python::error_already_set&)
  
    PyErr_Print();
    return 1;
  

  // Do not call Py_Finalize() with Boost.Python.

嵌入 Python 时,可能需要通过 PYTHONPATH 扩充 module search path,以便可以从自定义位置导入模块。

// Allow Python to load modules from the current directory.
setenv("PYTHONPATH", ".", 1);
// Initialize Python.
Py_Initialize();

通常,Boost.Python API 提供了一种以 Python 方式编写 C++ 代码的方法。以下示例 demonstrates 在 C++ 中嵌入 Python 解释器,并让 C++ 从磁盘导入 MyPythonClass Python 模块,实例化 MyPythonClass.Dog 的实例,然后在 Dog 实例上调用 bark()

#include <boost/python.hpp>
#include <cstdlib> // setenv

int main()

  // Allow Python to load modules from the current directory.
  setenv("PYTHONPATH", ".", 1);
  // Initialize Python.
  Py_Initialize();

  namespace python = boost::python;
  try
  
    // >>> import MyPythonClass
    python::object my_python_class_module = python::import("MyPythonClass");

    // >>> dog = MyPythonClass.Dog()
    python::object dog = my_python_class_module.attr("Dog")();

    // >>> dog.bark("woof");
    dog.attr("bark")("woof");
  
  catch (const python::error_already_set&)
  
    PyErr_Print();
    return 1;
  

  // Do not call Py_Finalize() with Boost.Python.

给定一个 MyPythonClass 模块,其中包含:

class Dog():
    def bark(self, message):
        print "The dog barks: ".format(message)

以上程序输出:

The dog barks: woof

【讨论】:

最后不应该打电话给Py_Finalize();吗? @TrevorHickey,没有。如Boost.Python embedding documentation 中所述,不应调用Py_Finalize() 来停止解释器。 如何隐藏 python 脚本文件内容?无论如何加密python文件但仍然在c ++运行时解密和调用python模块? @TannerSansbury,这是一个很好的答案。请建议将您评论中的全部信息添加到官方 Boost.python 文档中。官方文档缺少此类信息。谢谢,对我帮助很大。 这是我的 Boost.Python 示例:github.com/koponomarenko/embed_python_in_cxx【参考方案2】:

Boost python 用于从 python 源调用 cplusplus 函数。很像 Perl xs 模块。

如果你在 main.cpp 中有一个函数 say bark(),你可以使用 boost python 将这个 main.cpp 转换成一个 python 可调用模块。

然后从python脚本(假设链接输出文件是main.so):

import main
main.bark()

【讨论】:

对不起,我想可能有一些误解。我必须在 C++ 环境中工作,所以我希望我的 C++ 程序直接使用 python 中的 Dog.bark() ......而不是在 python 中跨度> Boost python 对你没有帮助。 boost 是一个 c++ 模块。试试这个docs.python.org/3/extending/embedding.html

以上是关于如何通过 Boost.Python 从 python 文件中导入函数的主要内容,如果未能解决你的问题,请参考以下文章

如何从 boost::python 返回 numpy.array?

boost::python - 如何从 C++ 在自己的线程中调用 python 函数?

如何使用 Boost Python 从 C++ bool 转换为 Python boolean?

在 boost.python 中;如何公开包含在另一个类中的类(通过组合)?

在 boost.python 中;如何公开包含在另一个类中的类(通过组合)?

如何使用 boost/python 向 python 公开 C++ 虚函数?