I'm using boost::python to embed some python code into an app. I was able to get print statements or other expressions to be evaluated properly, but when I try to import modules, it is not importing and application is exiting. Further the globals() function call in the embedded code gives a runtime error too.
我正在使用boost :: python将一些python代码嵌入到应用程序中。我能够正确地评估print语句或其他表达式,但是当我尝试导入模块时,它不会导入并且应用程序正在退出。此外,嵌入代码中的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);
}
Here, I've tried to import urllib2 using the boost import function, this compiles and runs properly, but with the following exec statement, it gives an error.
在这里,我尝试使用boost import函数导入urllib2,这会编译并正常运行,但是使用以下exec语句,它会出错。
object ignored = exec(
"print urllib2\n"
"print 'time'\n", main_namespace);
Or when I remove the boost import function and do the import from within the embedded code also, it gives an error. I tried using a try: except: block but that doesn't work either. Is this because the C++ app isn't able to find the location of the urllib2 py module or something? Is there a way to set the path of the module before trying to import?
或者当我删除boost导入函数并从嵌入代码中导入时,它会出错。我尝试使用try:except:block但这也不起作用。这是因为C ++应用程序无法找到urllib2 py模块的位置或其他什么?有没有办法在尝试导入之前设置模块的路径?
This is being built only for internal use, so some hard coding of the paths is acceptable.
这是为内部使用而构建的,因此可以接受一些路径的硬编码。
Edit: More info:
This is what happens. I did a try .. catch and called the PyErr_Print() when ever there is an exception, and got this as error all the time when there are module imports or even function calls. Error message:
编辑:更多信息:这就是发生的事情。我做了一次尝试..捕获并在有异常时调用PyErr_Print(),并且在模块导入甚至函数调用时始终将其作为错误。错误信息:
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: 'NoneType' object does not support item assignment
Can anyone think of any reason?
谁能想到任何理由?
3 个解决方案
#1
If you haven't already, you need to
如果你还没有,你需要
import sys sys.path.append("/home/user/whatever")
That took care of my problems a couple of years ago when embedding boost::python (Python v2.5).
几年前嵌入boost :: python(Python v2.5)时,这解决了我的问题。
Edit:
Poked around in old code. Perhaps this does the trick:
用旧代码戳了戳。也许这就是诀窍:
Py_SetProgramName(argv[0]); Py_InitializeEx(0);
Sounds unsure that you should really need the Py_SetProgramName()
, but I faintly remember some fishy business there.
听起来不确定你真的需要Py_SetProgramName(),但我依旧记得那里有些愚蠢的生意。
#2
That didn't help, but I found a different solution to my problem. My current code looks like this:
这没有用,但我找到了解决问题的不同方法。我当前的代码如下所示:
#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();
}
}
Anyways, thanks for the answer Jonas
无论如何,谢谢Jonas的回答
#3
I ran into the same problem as you, i e a very simple example resulting in the TypeError, and found the answer in this question, which was to supply the namespace twice, both as global and local.
我遇到了和你一样的问题,我是一个非常简单的例子,导致了TypeError,并在这个问题中找到了答案,即提供两次命名空间,包括全局和本地。
#1
If you haven't already, you need to
如果你还没有,你需要
import sys sys.path.append("/home/user/whatever")
That took care of my problems a couple of years ago when embedding boost::python (Python v2.5).
几年前嵌入boost :: python(Python v2.5)时,这解决了我的问题。
Edit:
Poked around in old code. Perhaps this does the trick:
用旧代码戳了戳。也许这就是诀窍:
Py_SetProgramName(argv[0]); Py_InitializeEx(0);
Sounds unsure that you should really need the Py_SetProgramName()
, but I faintly remember some fishy business there.
听起来不确定你真的需要Py_SetProgramName(),但我依旧记得那里有些愚蠢的生意。
#2
That didn't help, but I found a different solution to my problem. My current code looks like this:
这没有用,但我找到了解决问题的不同方法。我当前的代码如下所示:
#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();
}
}
Anyways, thanks for the answer Jonas
无论如何,谢谢Jonas的回答
#3
I ran into the same problem as you, i e a very simple example resulting in the TypeError, and found the answer in this question, which was to supply the namespace twice, both as global and local.
我遇到了和你一样的问题,我是一个非常简单的例子,导致了TypeError,并在这个问题中找到了答案,即提供两次命名空间,包括全局和本地。