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.
#include
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.
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?
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:
Traceback (most recent call last):
File "", line 1, in
TypeError: 'NoneType' object does not support item assignment
Can anyone think of any reason?
解决方案
That didn't help, but I found a different solution to my problem. My current code looks like this:
#include
#include
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(read);
cout << strResponse << endl;
}
catch(...)
{
PyErr_Print();
PyErr_Clear();
}
}
Anyways, thanks for the answer Jonas