python - C++ 嵌入式解释器和对象

Posted

技术标签:

【中文标题】python - C++ 嵌入式解释器和对象【英文标题】:python - c++ embedded interpreter and objects 【发布时间】:2019-08-21 00:58:19 【问题描述】:

我有一个简单的 C++ 程序,它启动一个嵌入式 python 解释器,导入一个模块并实例化该模块中定义的一个类。

我想了解为什么python对象的地址(从python的角度来看)和C++对象的地址不同。

python 实例和该实例的 c++ 视图有何不同的内存地址?

这是一些工作代码,使用pybind11:

#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>

using namespace std;
namespace py = pybind11;

int main()

    
        py::scoped_interpreter guard;
        py::module m = py::module::import("code");
        py::object o = m.attr("SomeClass")();
        cout << "[C++   ] object lives in " << &o << endl;
    
    return 0;

def message_from_python(*args):
    print('[PYTHON]', *args)


class SomeClass:
    def __init__(self):
        message_from_python(self, 'being created')

    def __del__(self):
        message_from_python(self, 'being deleted')

编译、执行和标准输出:

$ g++ -O3 -Wall -std=c++14 `python3 -m pybind11 --includes` code.cc -o code -lpython3.6m
$ ./code
[PYTHON] <code.SomeClass object at 0x7fb6926f1da0> being created
[C++   ] object lives in 0x7fffbed02588                   
[PYTHON] <code.SomeClass object at 0x7fb6926f1da0> being deleted

【问题讨论】:

对不起,我迟到了,但是你是怎么得到这个 -lpython3.6m 标志的?我找不到任何有关它的信息,幸运的是,我找到了您的帖子,它允许我的代码工作 @Joachim 我希望能提供更多帮助,但这是前段时间,我不记得我是如何使用该命令行的。我不太习惯与 g++ 打交道,所以即使现在我也不知道这样做的理由。我想我是从docs.python.org/3/extending/… 【参考方案1】:

如果我们快速查看 py::object 在其声明 here 中的组成部分,您会发现该类将 PyObject * 作为受保护成员(继承自 py::handle)。这个指针包含你看到从 python 端打印出来的地址。如果您可以访问它,您会看到它

cout << o.mptr << endl;

产生与 python shell 指示的相同的地址。

【讨论】:

我可以访问它! PyObject *ptr() const return m_ptr; . 啊,我错过了。我在 c++ 方面不是超级敏捷。

以上是关于python - C++ 嵌入式解释器和对象的主要内容,如果未能解决你的问题,请参考以下文章

Matplotlib 和 C++ 中嵌入式 python 的子解释器

从 C++ 嵌入式解释器捕获 python 窗口输出

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

如何中断嵌入在 C++ 应用程序中的 python 解释器

在 C++ 中嵌入 Python:解释器在执行过程中的持久性

在 Qt C++ 应用程序中创建 python 解释器小部件的简单方法?