Как импортировать модули во встроенный код Python boost::python?
-
06-09-2019 - |
Вопрос
Я использую 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 и выполняю импорт также из встроенного кода, это выдает ошибку.Я попробовал использовать попытку:кроме:блокировать, но это тоже не работает.Это потому, что приложение 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
Может ли кто-нибудь придумать какую-нибудь причину?
Решение 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();
}
}
В любом случае, спасибо за ответ, Джонас
Другие советы
Если вы еще этого не сделали, вам нужно
import sys sys.path.append("/home/user/whatever")
Это решило мои проблемы пару лет назад при встраивании boost::python (Python v2.5).
Редактировать:
Покопался в старом коде.Возможно, это поможет:
Py_SetProgramName(argv[0]); Py_InitializeEx(0);
Звучит неуверенно, что вам действительно нужно Py_SetProgramName()
, но я смутно помню там какое-то подозрительное дело.
Я столкнулся с той же проблемой, что и вы, то есть с очень простым примером, приводящим к ошибке TypeError, и нашел ответ в этот вопрос, который должен был предоставить пространство имен дважды, как глобальное, так и локальное.