Python/C++ 互操作性
Python/C++ Interoperabilty
我想扩展我的 C++ 应用程序以包含 Python 解释器。经过一番研究,boost.python 似乎是我想要的。但不知何故我无法让它工作。基本上我想用我的 C++ 应用程序加载和执行 Python 脚本。我将传递 PyEditor class 的实例,然后脚本可以调用各种方法。我使用回调机制来通知脚本更改。
现在我无法编译我的代码。它一直告诉我
libs/boost-1.5.8/boost/python/module_init.hpp:79:8: error: expected unqualified-id before string constant
extern "C" __attribute__ ((__visibility__("default"))) _BOOST_PYTHON_MODULE_INIT(name)
libs/boost-1.5.8/boost/python/module.hpp:11:30: note: in expansion of macro ‘BOOST_PYTHON_MODULE_INIT’
# define BOOST_PYTHON_MODULE BOOST_PYTHON_MODULE_INIT
这是我加载脚本的函数
void PythonManager::LoadModules()
{
BOOST_PYTHON_MODULE(PyManager)
{
boost::python::class_<PyEditor>("PyEditor", boost::python::no_init)
.def("GetText",&PyEditor::GetText)
.def("GetText",&PyEditor::SetText)
.def("AddCallable",&PyEditor::AddCallable);
}
PyImport_AppendInittab("PyManager");
Py_Initialize();
boost::python::object pyManagerModule((handle<>(PyImport_ImportModule("PyManager"))));
main_namespace["PyManager"] = pyManagerModule;
scope(cpp_module).attr("editor") = boost::python::ptr(new PyEditor());
//Load the .py files
}
我已经阅读了几乎所有可能的资源,但我无法理解我的错误
BOOST_PYTHON_MODULE
macro is syntax sugar for declaring a Python module initialization function。编译器抱怨尝试定义嵌套命名函数。将 BOOST_PYTHON_MODULE
块移动到允许定义命名函数的范围,例如全局命名空间,应该可以解决问题:
BOOST_PYTHON_MODULE(PyManager)
{
...
}
void PythonManager::LoadModules()
{
PyImport_AppendInittab("PyManager", &initPyManager);
...
}
这是一个完整的例子demonstrating在嵌入时导入一个静态链接的Python模块:
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(example)
{
boost::python::def("calc", +[](int x) { return x * 2; });
}
int main()
{
namespace python = boost::python;
try
{
PyImport_AppendInittab("example", &initexample);
Py_Initialize(); // Start interpreter.
// Create the __main__ module.
python::object main = python::import("__main__");
python::object main_namespace = main.attr("__dict__");
// >>> import example
main_namespace["example"] = python::import("example");
// >>> assert(42 == example.calc(21))
python::object result = main_namespace["example"].attr("calc")(21);
assert(42 == python::extract<int>(result)());
}
catch (const python::error_already_set&)
{
PyErr_Print();
}
}
以上程序运行完成没有错误,并且在注释中注释了等效的 Python 代码。
我想扩展我的 C++ 应用程序以包含 Python 解释器。经过一番研究,boost.python 似乎是我想要的。但不知何故我无法让它工作。基本上我想用我的 C++ 应用程序加载和执行 Python 脚本。我将传递 PyEditor class 的实例,然后脚本可以调用各种方法。我使用回调机制来通知脚本更改。
现在我无法编译我的代码。它一直告诉我
libs/boost-1.5.8/boost/python/module_init.hpp:79:8: error: expected unqualified-id before string constant extern "C" __attribute__ ((__visibility__("default"))) _BOOST_PYTHON_MODULE_INIT(name) libs/boost-1.5.8/boost/python/module.hpp:11:30: note: in expansion of macro ‘BOOST_PYTHON_MODULE_INIT’ # define BOOST_PYTHON_MODULE BOOST_PYTHON_MODULE_INIT
这是我加载脚本的函数
void PythonManager::LoadModules()
{
BOOST_PYTHON_MODULE(PyManager)
{
boost::python::class_<PyEditor>("PyEditor", boost::python::no_init)
.def("GetText",&PyEditor::GetText)
.def("GetText",&PyEditor::SetText)
.def("AddCallable",&PyEditor::AddCallable);
}
PyImport_AppendInittab("PyManager");
Py_Initialize();
boost::python::object pyManagerModule((handle<>(PyImport_ImportModule("PyManager"))));
main_namespace["PyManager"] = pyManagerModule;
scope(cpp_module).attr("editor") = boost::python::ptr(new PyEditor());
//Load the .py files
}
我已经阅读了几乎所有可能的资源,但我无法理解我的错误
BOOST_PYTHON_MODULE
macro is syntax sugar for declaring a Python module initialization function。编译器抱怨尝试定义嵌套命名函数。将 BOOST_PYTHON_MODULE
块移动到允许定义命名函数的范围,例如全局命名空间,应该可以解决问题:
BOOST_PYTHON_MODULE(PyManager)
{
...
}
void PythonManager::LoadModules()
{
PyImport_AppendInittab("PyManager", &initPyManager);
...
}
这是一个完整的例子demonstrating在嵌入时导入一个静态链接的Python模块:
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(example)
{
boost::python::def("calc", +[](int x) { return x * 2; });
}
int main()
{
namespace python = boost::python;
try
{
PyImport_AppendInittab("example", &initexample);
Py_Initialize(); // Start interpreter.
// Create the __main__ module.
python::object main = python::import("__main__");
python::object main_namespace = main.attr("__dict__");
// >>> import example
main_namespace["example"] = python::import("example");
// >>> assert(42 == example.calc(21))
python::object result = main_namespace["example"].attr("calc")(21);
assert(42 == python::extract<int>(result)());
}
catch (const python::error_already_set&)
{
PyErr_Print();
}
}
以上程序运行完成没有错误,并且在注释中注释了等效的 Python 代码。