Как импортировать модули в boost: python embedded python code?
Я использую 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);
}
Здесь я попытался импортировать urllib2 с помощью функции импорта boost, это компилируется и запускается правильно, но со следующей инструкцией exec выдает ошибку.
object ignored = exec(
"print urllib2\n"
"print 'time'\n", main_namespace);
Или, когда я удаляю функцию импорта boost и выполняю импорт из встроенного кода, он дает ошибку. Я попытался использовать try: except: block, но это тоже не работает. Это потому, что приложение С++ не может найти расположение модуля urllib2 py или что-то еще? Есть ли способ установить путь к модулю перед попыткой импорта?
Это создается только для внутреннего использования, поэтому допустимо некоторая жесткая кодировка путей.
Изменить: Подробнее:
Вот что происходит. Я сделал попытку.. поймал и назвал PyErr_Print(), когда когда-либо было исключение, и получил это как ошибку все время, когда есть импорт модулей или даже вызовы функций. Сообщение об ошибке:
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: 'NoneType' object does not support item assignment
Может кто-нибудь подумать о какой-либо причине?
Ответы
Ответ 1
Это не помогло, но я нашел другое решение для своей проблемы. Мой текущий код выглядит следующим образом:
#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();
}
}
В любом случае, спасибо за ответ Jonas
Ответ 2
Если вы еще этого не сделали, вам нужно
import sys
sys.path.append("/home/user/whatever")
Это позаботилось о моих проблемах пару лет назад при внедрении boost:: python (Python v2.5).
Edit:
Пытается в старом коде. Возможно, это делает трюк:
Py_SetProgramName(argv[0]);
Py_InitializeEx(0);
Звучит неуверенно, что вам действительно нужно Py_SetProgramName()
, но я слабо помню какой-то рыбный бизнес там.
Ответ 3
Я столкнулся с той же проблемой, что и вы, т.е. очень простой пример, приводящий к TypeError, и нашел ответ в этом вопросе, который должен был предоставить пространство имен дважды, как глобальные, так и локальные.