1

ブースト python を使用して、C++ アプリケーションに python を埋め込んでいます。

ブースト python 関数オブジェクトを呼び出し、グローバル名前空間をその関数呼び出しに関連付けられるようにしたいと考えています。具体的には、簡略化された関連コードは次のとおりです。

bp::object main = bp::import("__main__");
bp::object main_namespace = main.attr("__dict__");


//Put the function name runPyProg in the main_namespace

bp::object PyProg = exec(
        "import cStringIO\n"
        "import sys\n"
        "sys.stderr = cStringIO.StringIO()\n"
        "def runPyProg(exp):\n"
        "    print exp\n"
        "    exec(exp)\n"
        "    return\n"
        "\n",main_namespace);

//Now call the python function runPyProg with an argument

bp::object py_fn = main.attr("runPyProg");
py_fn(expStr)

上記のように、boost python exec() 関数を使用すると、グローバル名前空間で送信できることがわかっています。私の質問は、py_fn を呼び出すときに main_namespace を python 関数に関連付ける方法です。最終的な目標は、runPyProg のローカル変数を main_namespace に配置することです。

ありがとうございました。

4

1 に答える 1

4

exec質問を正しく理解していれば、実行するコンテキストを指定するのと同じくらい簡単なはずです。関数またはメソッドは、 を介して定義されている名前空間にアクセスできますglobals()globals()したがって、内部から呼び出すとrunPyProg()、Python に相当する が返されますmain_namespace。さらに、exec次の 2 つのオプションの引数を取ります。

  • 最初の引数は、 に使用される辞書を指定しますglobals()。2 番目の引数を省略すると、 にも使用されlocals()ます。
  • 2 番目の引数は、 に使用される辞書を指定しますlocals()。内で発生した変数の変更execは に適用されlocals()ます。

したがって、次のように変更します。

exec exp

exec exp in globals()

expでグローバル変数とやり取りできる場所で、目的の動作を提供する必要がありますmain_namespace


以下に基本的な例を示します。

#include <boost/python.hpp>

int main()
{
  Py_Initialize();

  namespace python = boost::python;
  python::object main = python::import("__main__");
  python::object main_namespace = main.attr("__dict__");

  //Put the function name runPyProg in the main_namespace
  python::exec(
    "def runPyProg(exp):\n"
    "    print exp\n"
    "    exec exp in globals()\n"
    "    return\n"
    "\n", main_namespace);

  // Now call the python function runPyProg with an argument
  python::object runPyProg = main.attr("runPyProg");

  // Set x in python and access from C++.
  runPyProg("x = 42");
  std::cout << python::extract<int>(main.attr("x")) << std::endl;

  // Set y from C++ and access within python.
  main.attr("y") = 100;
  runPyProg("print y");

  // Access and modify x in python, then access from C++.
  runPyProg("x += y");
  std::cout << python::extract<int>(main.attr("x")) << std::endl;
}

コメント付きの出力:

x = 42          // set from python
42              // print from C++
                // y set to 100 from C++
print y         // print y from python
100             //
x += y          // access and modify from python
142             // print x from C++
于 2013-05-13T14:54:34.510 に答える