Python 3 C-API IO и выполнение файлов
-
25-09-2019 - |
Вопрос
У меня есть серьезные проблемы с получением двигателя C ++ на базе Python 2 для работы в Python3. Я знаю, весь стек IO изменился, но все, что я, кажется, пытаюсь, заканчивается неудачей. Ниже приведен предварительный код (Python2) и почтовый код (Python3). Я надеюсь, что кто-то может помочь мне выяснить, что я делаю неправильно. Я также использую boost::python
контролировать ссылки.
Программа должна загружать объект Python в память через карту, а затем при использовании функции запуска, то он находит файл загружен в память и запускает его. Я основал свой код от примера от Delta3d Python Manager, где они загружаются в файл и выполняют его немедленно. Я не видел ничего, эквивалентного в Python3.
Код Python2 начинается здесь:
// what this does is first calls the Python C-API to load the file, then pass the returned
// PyObject* into handle, which takes reference and sets it as a boost::python::object.
// this takes care of all future referencing and dereferencing.
try{
bp::object file_object(bp::handle<>(PyFile_FromString(fullPath(filename), "r" )));
loaded_files_.insert(std::make_pair(std::string(fullPath(filename)), file_object));
}
catch(...)
{
getExceptionFromPy();
}
Далее я загружаю файл с STD :: Map и попытаться выполнить его:
bp::object loaded_file = getLoadedFile(filename);
try
{
PyRun_SimpleFile( PyFile_AsFile( loaded_file.ptr()), fullPath(filename) );
}
catch(...)
{
getExceptionFromPy();
}
Код Python3 начинается здесь: это то, что у меня так далеко на основе некоторых предложений здесь ... Поэтому вопросНагрузка:
PyObject *ioMod, *opened_file, *fd_obj;
ioMod = PyImport_ImportModule("io");
opened_file = PyObject_CallMethod(ioMod, "open", "ss", fullPath(filename), "r");
bp::handle<> h_open(opened_file);
bp::object file_obj(h_open);
loaded_files_.insert(std::make_pair(std::string(fullPath(filename)), file_obj));
Бегать:
bp::object loaded_file = getLoadedFile(filename);
int fd = PyObject_AsFileDescriptor(loaded_file.ptr());
PyObject* fileObj = PyFile_FromFd(fd,fullPath(filename),"r",-1,"", "\n","", 0);
FILE* f_open = _fdopen(fd,"r");
PyRun_SimpleFile( f_open, fullPath(filename) );
Наконец, общее состояние программы в этот момент является файл загружается как TextIOWrapper
и в бегах: раздел FD, который возвращается, всегда 3 и по какой-то причине _fdopen
никогда не могу открыть FILE
что означает, что я не могу сделать что-то вроде PyRun_SimpleFile
. Отказ Сама ошибка - отладка ASSERTION
на _fdopen
. Отказ Есть ли лучший способ сделать все это, я действительно ценю любую помощь.
Если вы хотите увидеть полную программу версии Python2, она на Гадость
Решение
Таким образом, этот вопрос был довольно трудно понять, и извините, но я узнал, что мой старый код не совсем работал, как я ожидал. Вот что я хотел, чтобы код сделал. Загрузите файл Python в память, храните его на карту, а затем с более поздней датой выполните этот код в памяти. Я достиг этого немного иначе, чем я ожидал, но сейчас это имеет много смысла.
- Откройте файл, используя Ifstream, см. Код ниже
- Конвертировать Char в Boost :: Python :: str
- Выполнить повышение :: Python :: ул. С повышением :: Python :: Exec
- Выгода ???
Шаг 1)
vector<char> input;
ifstream file(fullPath(filename), ios::in);
if (!file.is_open())
{
// set our error message here
setCantFindFileError();
input.push_back('\0');
return input;
}
file >> std::noskipws;
copy(istream_iterator<char>(file), istream_iterator<char>(), back_inserter(input));
input.push_back('\n');
input.push_back('\0');
Шаг 2) BP :: str file_str (строка (и ввод [0])); loaded_files_.insert (std :: make_pair (std :: string (fullpath (filename)), file_str)); Шаг 3)
bp::str loaded_file = getLoadedFile(filename);
// Retrieve the main module
bp::object main = bp::import("__main__");
// Retrieve the main module's namespace
bp::object global(main.attr("__dict__"));
bp::exec(loaded_file, global, global);
Полный код находится на гадость: