C++アプリケーションでboost::python
を使用してPythonスクリプトファイルを読み込んで関数を呼び出すことができました。boost :: python:C++アプリケーションをC++アプリケーションに埋め込まれたPythonスクリプトに公開する
ブーストのpython EmbeddingPython wikiには、how to load a python moduleというヒントがあります。
テストを:
namespace bp = boost::python;
bp::object import(const std::string& module, const std::string& path, bp::object& globals)
{
bp::dict locals;
locals["module_name"] = module;
locals["path"] = path;
bp::exec("import imp\n"
"new_module = imp.load_module(module_name, open(path), path, ('py', 'U', imp.PY_SOURCE))\n",
globals,
locals);
return locals["new_module"];
}
私は正常
int main()
{
Py_Initialize();
bp::object main = bp::import("__main__");
bp::object globals = main.attr("__dict__");
bp::object module = import("test", "test.py", globals);
bp::object run = module.attr("run");
run();
return 0;
}
こんにちは、世界で上記のコードを実行するtest.py
スクリプトが正常に動作Pythonモジュール(test.py
)をインポートするためにこれを使用することができます。 py:
def run():
print "hello world"
出力:パイソンのC++クラスの公開
hello world
:
はしかし、私は今、そのスクリプトにC++クラスを公開します。 boost::python
ドキュメントを1として
struct Foo
{
void f() {}
};
、次のように私は、このクラスを公開:上記のリンクウィキ内の命令を1として
BOOST_PYTHON_MODULE(FooModule)
{
bp::class_<Foo>("Foo")
.def("f", &Foo::f)
;
}
を、私はその後、私のFooModule
をインポートして、私の中でそれを保存することができますglobals
:
PyImport_AppendInittab("FooModule", &initFooModule);
...
bp::object Foo = bp::import("FooModule");
globals["Foo"] = Foo;
このインポートは私をインポートする前にをやっていますこのglobals
オブジェクトは、スクリプトをインポートするときにbp::exec
に渡されるものです(つまり、Foo
はになる必要があります)。bp::exec
はインポート時にスクリプトに公開されます。
しかし、何らかの理由で私のFoo
モジュールがない見え
test.py
にある質問:
どのように私はロードしていますtest.py
Pythonスクリプトに私のFoo
クラスを公開することができますか?
全作業例:
test.py
:
def run():
foo = Foo()
foo.f()
main.cpp
:
#include <iostream>
#include <boost/python.hpp>
namespace bp = boost::python;
bp::object import(const std::string& module, const std::string& path, bp::object& globals)
{
bp::dict locals;
locals["module_name"] = module;
locals["path"] = path;
bp::exec("import imp\n"
"new_module = imp.load_module(module_name, open(path), path, ('py', 'U', imp.PY_SOURCE))\n",
globals,
locals);
return locals["new_module"];
}
struct Foo
{
void f() {}
};
BOOST_PYTHON_MODULE(FooModule)
{
bp::class_<Foo>("Foo")
.def("f", &Foo::f)
;
}
int main()
try
{
PyImport_AppendInittab("FooModule", &initFooModule);
Py_Initialize();
// get a handle to the globals dict
bp::object main = bp::import("__main__");
bp::object globals = main.attr("__dict__");
// import FooModule, and store it in the globals dict
bp::object Foo = bp::import("FooModule");
globals["Foo"] = Foo;
// import the test script, passing the populated globals dict
bp::object module = import("test", "test.py", globals);
bp::object run = module.attr("run");
// run the script
run();
return 0;
}
catch(const bp::error_already_set&)
{
std::cerr << ">>> Error! Uncaught exception:\n";
PyErr_Print();
return 1;
}
Output
:
>>> Error! Uncaught exception: Traceback (most recent call last): File "test.py", line 2, in run foo = Foo() NameError: global name 'Foo' is not defined
注意上記を行う際に、これを見ている人は、 'bp :: import(" FooModule ");'はもう必要ありません。 'PyImport_AppendInittab'への呼び出しは、スクリプトが' FooModule'をインポートするために必要なものです。 –