[英]boost::python: expose a C++ class to a python script embedded in a C++ app
我能夠成功加載python腳本文件並在C ++應用程序中使用boost::python
來調用函數。
在Boost python EmbeddingPython Wiki中,有關於如何加載python模塊的提示 。
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"];
}
我可以成功地使用它導入python模塊( test.py
)
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;
}
使用hello-world test.py
腳本運行上述代碼可以正常工作:
test.py:
def run():
print "hello world"
輸出:
hello world
但是,我現在想向該腳本公開C ++類。
struct Foo
{
void f() {}
};
根據boost::python
文檔,我將此類公開如下:
BOOST_PYTHON_MODULE(FooModule)
{
bp::class_<Foo>("Foo")
.def("f", &Foo::f)
;
}
按照上面鏈接的Wiki中的說明,然后我可以導入FooModule
,並將其存儲在我的globals
:
PyImport_AppendInittab("FooModule", &initFooModule);
...
bp::object Foo = bp::import("FooModule");
globals["Foo"] = Foo;
該導入是在導入我的test.py
腳本之前完成的,並且此globals
對象是導入我的腳本時傳遞給bp::exec
對象(即: Foo
應該位於bp::exec
暴露給我的腳本的globals dict中。輸入)。
但是,由於某些原因, test.py
無法看到我的Foo
模塊
如何將我的Foo
類暴露給我正在加載的test.py
python腳本?
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
與其嘗試從C ++端將FooModule
注入Python腳本, PyImport_AppendInittab
從C ++端向PyImport_AppendInittab
注冊模塊,然后從Python端import
它:
import FooModule
def run():
foo = FooModule.Foo()
foo.f()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.