Я встраиваю Python в приложение Larger C ++, используя Python C API. Моя цель - создать игру, которая будет обучать программированию с использованием Python, и игрок на самом деле набирает код Python, поэтому я встраиваю интерпретатор. Я знаю, что Boost и Cython существуют, но для моих нужд C API работает довольно хорошо, теперь, когда я правильно собираю аргументы Python, у меня может быть тип игрока в игровых арифметических функциях Python без переменных 2 + 2
вигра печатает 4
в игру правильно. Однако, когда вызывается функция Python, такая как print("Hello World")
мой код для перевода из значения Python обратно в C, а затем API всегда печатает None
в игре, но правильное значение в командной строке отладки. После запуска проверки ошибок для Python C API, я сначала запускаю следующие строки:
PyObject* result = PyRun_String(cPlayerString, Py_eval_input, globalDictionary, localDictionary);
auto str = PyToStr(result);
std::string resString(str.begin(), str.end());;
Код в PyToStr(object)
выглядит следующим образом:
std::wstring Level_System::PyToStr(PyObject* Object)
{
//storeOut.open("store.txt");
//it is equivalent to python code : str(Object)
PyObject* objectsRepresentation = PyObject_Str(Object);
//convert Python String Object to C++ wchar_t*
const wchar_t* ws = PyUnicode_AsUnicode(objectsRepresentation);
if (ws)
{
writeToFile(ws);
return ws;
}
//if ws is NULL it could not be converted implicitly to std::wstring
return L"";
}
Когда return ws
не арифметическое значение, он выводит полученный код правильно на консоль отладки, но не выводит значения на консоль. Мой первый: проверка типов данных и того, что сохраняется, используя строки cout
, чтобы увидеть, преобразовывается ли он обратно в правильный тип данных C / C ++:
std::cout << "resString typeid is: " << typeid(resString).name() << std::endl;
std::cout << "resString data stored is : " << resString.data() << std::endl;
std::cout << resString << std::endl;
Этот код показал: данные строки результатабыл нулевым при вызове функции Python, но был эквивалентен непосредственному значению символа любой арифметической функции. Во-вторых, я записал строку ws
в простой текстовый файл, чтобы убедиться, что он даже правильно создает представление Unicode:
void Level_System::writeToFile(std::wstring writeVal) {
storeFile.open("store.txt");
//do I call and pass in the PyToString(Object) function here
if (storeFile.is_open()) {
storeFile.clear(); //clear the previous value in the file
storeFile << writeVal; //write the value in ws to file
}
storeFile.close();
}
Это всегда записывает None, за которым следует случайный ряд цифр и букв. если вызывается функция Python, такая как print
, или непосредственное арифметическое значение математического вычисления, за которым следует Unicode, в файл .txt. Я не уверен, нужно ли мне добавлять другое преобразование типов данных для захвата значения ws
независимо от простой арифметики или вызываемой функции, мне нужно захватить значение ws
другим способом (хотя я ненашел что-нибудь о передаче объектов Python через аргументы в API, что, вероятно, было бы вещью на языке C (или я не уверен в синтаксисе для этого), или что-то совсем другое - не сбор надлежащих данных с помощью вызовов API.
Поскольку этот проект является моим старшим проектом capstone, если я могу каждый раз получать правильное значение для текстового файла, я думаю, что это может быть обходной путь, чтобы проект работал с параметрами старшего проекта.
Заранее спасибо!