如何在 boost::python 嵌入式 python 代码中导入模块?
Posted
技术标签:
【中文标题】如何在 boost::python 嵌入式 python 代码中导入模块?【英文标题】:How do I import modules in boost::python embedded python code? 【发布时间】:2009-06-02 04:23:02 【问题描述】:我正在使用 boost::python 将一些 python 代码嵌入到应用程序中。我能够正确评估打印语句或其他表达式,但是当我尝试导入模块时,它没有导入并且应用程序正在退出。此外,嵌入式代码中的 globals() 函数调用也会产生运行时错误。
#include <boost/python.hpp>
using namespace boost;
using namespace boost::python;
using namespace boost::python::api;
int main(void)
Py_Initialize();
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
main_namespace["urllib2"] = import("urllib2");
object ignored = exec(
"print 'time'\n", main_namespace);
这里,我尝试使用boost导入函数导入urllib2,编译运行正常,但是使用下面的exec语句,报错。
object ignored = exec(
"print urllib2\n"
"print 'time'\n", main_namespace);
或者当我删除 boost 导入功能并从嵌入式代码中进行导入时,它会给出错误。我尝试使用 try: except: block 但这也不起作用。这是因为 C++ 应用程序无法找到 urllib2 py 模块的位置还是什么?有没有办法在尝试导入之前设置模块的路径?
这只是为内部使用而构建的,因此可以接受一些路径的硬编码。
编辑:更多信息: 这就是发生的事情。我尝试了.. catch 并在出现异常时调用 PyErr_Print() ,并且在有模块导入甚至函数调用时一直将其视为错误。错误信息:
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: 'NoneType' object does not support item assignment
谁能想到任何理由?
【问题讨论】:
【参考方案1】:如果你还没有,你需要
导入系统 sys.path.append("/home/user/whatever")几年前嵌入 boost::python (Python v2.5) 时,这解决了我的问题。
编辑:
在旧代码中四处寻找。也许这可以解决问题:
Py_SetProgramName(argv[0]); Py_InitializeEx(0);听起来不确定您是否真的需要Py_SetProgramName()
,但我隐约记得那里有一些可疑的事情。
【讨论】:
感谢您的回复,真的感谢您延迟尝试并告诉您,乔纳斯。我试过了,但这没有帮助。如果它有这个单一的语句“print globals()\n”,我什至无法让程序运行。我在 windows 和 linux 上尝试了相同的代码,并且到处都有相同的响应。我正在使用 Boost 1.39.0 我在导入某些库(例如 gzip 或 numpy)时遇到了一个神秘的分段错误。然后这个 hack 像一个魅力一样解决了这个问题:Py_SetProgramName("");
Py_InitializeEx(0);
Thanks @Jonas【参考方案2】:
这没有帮助,但我找到了一个不同的解决方案来解决我的问题。我当前的代码如下所示:
#include <boost/python.hpp>
#include <iostream>
using namespace std;
using namespace boost;
using namespace boost::python;
using namespace boost::python::api;
int main(void)
Py_Initialize();
boost::python::object http = boost::python::import("urllib2");
try
boost::python::object response = http.attr("urlopen")("http://www.google.com");
boost::python::object read = response.attr("read")();
std::string strResponse = boost::python::extract<string>(read);
cout << strResponse << endl;
catch(...)
PyErr_Print();
PyErr_Clear();
无论如何,谢谢乔纳斯的回答
【讨论】:
很高兴您的代码可以正常工作。你想用它做什么? 哦。我完全厌倦了 C++ 套接字库。他们需要时间来理解,而且由于我不是计算机专业的学生,所以我需要更长的时间来理解。所以我创建了一个感觉像异步 urllib++ 的东西,后面有 python urllib2。 :D 我知道这听起来很疯狂。但是我现在有一个非常方便的解决方案!【参考方案3】:我遇到了和你一样的问题,即一个导致 TypeError 的非常简单的示例,并在 this question 中找到了答案,即提供两次命名空间,作为全局和本地。
【讨论】:
以上是关于如何在 boost::python 嵌入式 python 代码中导入模块?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Boost.Python 在 Python 中调用内置函数
使用 Boost::Python 从嵌入式 python 中提取数据
Embedded Boost::Python 和 C++:并行运行