3

我正在将 Python 嵌入到 C++ 应用程序中。当我在 Python 中创建一个新对象时,我希望能够在我的 C++ 应用程序中存储对该对象的引用,以便以后可以调用该对象的方法。这样做的推荐方法是什么?

例如,我希望能够做这样的事情:

实体.py

class Entity:
    def getPointer(self)
        return pointertoSelf;

管理器.cpp

Py_Initialize();
PyRun_SimpleString("import Entity");
PyRun_SimpleString("entity = Entity.Entity()");

pointerToPythonObj* = somehowGetPointerToObj("entity");
4

1 回答 1

2

推荐的方法是查询entity创建对象的命名空间,然后将对象的句柄存储entityboost::python::object. 从 C++ 与 Python 对象交互时,最好尽可能使用boost::python::object它,因为它提供了一种类似于 Python 变量的高级表示法。此外,它提供了适当的引用计数来管理 Python 对象的生命周期。例如,存储原始指针(即pointerToPythonObj*)不会延长 Python 对象的生命周期;如果 Python 对象是从解释器内部收集的垃圾,那么pointerToPythonObj它将是一个悬空指针。


下面是一个例子来证明这一点:

实体.py:

class Entity:
    def action(self):
        print "in Entity::action"

主.cpp:

#include <boost/python.hpp>

int main()
{
  namespace python = boost::python;
  try
  {
    Py_Initialize(); // Start interpreter.

    // Create the __main__ module.
    python::object main = python::import("__main__");
    python::object main_namespace = main.attr("__dict__");

    // Import Entity.py, and instantiate an Entity object in the
    // global namespace.  PyRun_SimpleString could also be used,
    // as it will default to running within and creating 
    // __main__'s namespace.
    exec(
        "import Entity\n"
        "entity = Entity.Entity()\n"
      , main_namespace
    );

    // Obtain a handle to the entity object created from the previous
    // exec.
    python::object entity = main_namespace["entity"];
    // Invoke the action method on the entity.
    entity.attr("action")();
  }
  catch (const python::error_already_set&)
  {
    PyErr_Print();
  }
}

运行上述程序会产生以下输出:

在实体::动作

如果Entity.py导入失败,则可能需要将其包含目录添加到PYTHONPATH环境变量中。

于 2013-08-05T14:13:23.620 回答