3

C++ アプリケーション内に Python を埋め込む作業を行っています。Python で新しいオブジェクトを作成するとき、そのオブジェクトへの参照を C++ アプリケーションに格納できるようにして、後でそのオブジェクトのメソッドを呼び出せるようにしたいと考えています。これを行うための推奨される方法は何ですか?

たとえば、次のようなことができるようにしたいと思います。

Entity.py

class Entity:
    def getPointer(self)
        return pointertoSelf;

Manager.cpp

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

pointerToPythonObj* = somehowGetPointerToObj("entity");
4

1 に答える 1

2

推奨される方法は、オブジェクトが作成された名前空間にクエリを実行してから、オブジェクトentityへのハンドルを として格納することです。C++ から Python オブジェクトを操作する場合は、可能な限り使用することをお勧めします。これは、Python 変数のように機能する高レベルの表記法を提供するためです。さらに、Python オブジェクトの有効期間を管理するための適切な参照カウントを提供します。たとえば、生のポインター (つまり) を保存しても、Python オブジェクトの寿命は延びません。Python オブジェクトがインタープリター内からガベージ コレクションされた場合、ダングリング ポインターになります。entityboost::python::objectboost::python::objectpointerToPythonObj*pointerToPythonObj


これを示す例を次に示します。

エンティティ.py:

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

main.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 に答える