首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >libboost-python在C++运行时创建模块,并从pythin代码中使用它,用于python 3.x

libboost-python在C++运行时创建模块,并从pythin代码中使用它,用于python 3.x
EN

Stack Overflow用户
提问于 2022-07-22 04:44:02
回答 1查看 75关注 0票数 0

我有一个使用libboost-python嵌入python的软件。它在C++运行时创建一个python模块,然后从python代码中导入它。

对于python2.7,它的工作方式如下:

test_module.py

代码语言:javascript
复制
import _hello_provider

test_var = 42

def hello_static():
        return "Hello world static"

def hello_provided():
        return _hello_provider.provide_hello()

test27.cpp

代码语言:javascript
复制
#include <boost/python.hpp>
 
std::string provide_hello() {
    return "hello world provided";
}
 
BOOST_PYTHON_MODULE(_hello_provider) {
    using namespace boost::python;
    def("provide_hello", &provide_hello);
}


int main()
{
  Py_InitializeEx(0);
  try {
    boost::python::object modImp = boost::python::import("imp");
    init_hello_provider();


    PyImport_AddModule("test_module");

    modImp.attr("load_source")("test_module", "test_module.py");

    boost::python::exec("print(test_var)", boost::python::import("test_module").attr("__dict__"));
    boost::python::exec("print(hello_static())", boost::python::import("test_module").attr("__dict__"));
    boost::python::exec("print(hello_provided())", boost::python::import("test_module").attr("__dict__"));
  }
  catch (const boost::python::error_already_set&)
  {
    PyErr_Print();
  }
  Py_Finalize();
}

在Debian扩展中,您可以这样构建它:

代码语言:javascript
复制
g++  test27.cpp  -I /usr/include/x86_64-linux-gnu/python2.7 -I /usr/include/python2.7 -lboost_python -lboost_system -lpython2.7

它如预期的那样工作。Python导入用_hello_provider代码创建的C++模块,并使用provide_hello()进行打印。

当我试图将它移植到python 3.x时,我得到了这样的代码:

test3x.cpp

代码语言:javascript
复制
#include <boost/python.hpp>
 
std::string provide_hello() {
    return "hello world provided";
}

BOOST_PYTHON_MODULE(_hello_provider) {
    using namespace boost::python;
    def("provide_hello", &provide_hello);
}


int main()
{
  Py_InitializeEx(0);
  try {
    boost::python::object modImp = boost::python::import("imp");
    PyInit__hello_provider();

    PyImport_AddModule("test_module");

    modImp.attr("load_source")("test_module", "test_module.py");

    boost::python::exec("print(test_var)", boost::python::import("test_module").attr("__dict__"));
    boost::python::exec("print(hello_static())", boost::python::import("test_module").attr("__dict__"));
    boost::python::exec("print(hello_provided())", boost::python::import("test_module").attr("__dict__"));
  }
  catch (const boost::python::error_already_set&)
  {
    PyErr_Print();
  }
  Py_Finalize();
}

它使用相同的test_module.py作为前面的示例。在Debian Bullseye上,您可以使用以下命令成功地构建它:

代码语言:javascript
复制
g++ test3x.cpp  -I /usr/include/x86_64-linux-gnu/python3.9 -I /usr/include/python3.9 -lpython3.9  -lboost_python39 -lboost_system

它将成功建造,但不会像预期的那样工作,他说

代码语言:javascript
复制
Traceback (most recent call last):
  File "/usr/lib/python3.9/imp.py", line 169, in load_source
    module = _exec(spec, sys.modules[name])
  File "<frozen importlib._bootstrap>", line 613, in _exec
  File "<frozen importlib._bootstrap_external>", line 790, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "test_module.py", line 1, in <module>
    import _hello_provider
ModuleNotFoundError: No module named '_hello_provider'

如果我从代码中删除“导入”部分,一切都会正常工作。

如何正确地用C++代码创建python模块并从libboost-python3.x中的python代码中导入?正确的方法是什么?

EN

回答 1

Stack Overflow用户

发布于 2022-07-23 07:03:40

这里的关键点是,在python3.x中,您应该使用PyImport_AppendInittab手动将这些模块添加到inittab(不管它是什么)

最后,我用2.7anx3.x pythons构建的示例如下所示

代码语言:javascript
复制
#include <boost/python.hpp>

std::string provide_hello() {
    return "hello world provided";
}

BOOST_PYTHON_MODULE(_hello_provider) {
    using namespace boost::python;
    def("provide_hello", &provide_hello);
}

int main()
{
#if PY_MAJOR_VERSION >= 3
  PyImport_AppendInittab((char*)"_hello_provider", PyInit__hello_provider);
#else
  PyImport_AppendInittab((char*)"_hello_provider", init_hello_provider);
#endif
  Py_InitializeEx(0);

  try {
    boost::python::object modImp = boost::python::import("imp");
    PyImport_AddModule("test_module");

    modImp.attr("load_source")("test_module", "test_module.py");

    boost::python::exec("print(test_var)", boost::python::import("test_module").attr("__dict__"));
    boost::python::exec("print(hello_static())", boost::python::import("test_module").attr("__dict__"));
    boost::python::exec("print(hello_provided())", boost::python::import("test_module").attr("__dict__"));
  }
  catch (const boost::python::error_already_set&)
  {
    PyErr_Print();
  }
  Py_Finalize();
}

特别感谢https://github.com/TNG/boost-python-examples/tree/main/10-Embedding作者和来自linux.org.ru的O02eg

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73075219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档