I am embedding Python in a Larger C++ application using the Python C API. My goal is to make a game that can teach programming using Python, and the player actually types in Python Code, which is why I'm embedding an interpreter. I am aware that Boost and Cython exist, but for my needs the C API is working quite well now that I'm capturing the Python arguments properly, I can have the player type in game Python Arithmetic functions with no variables 2 + 2
in the game prints 4
to the game properly. However, when a Python function is called, such as print("Hello World")
my code to translate from the Python value back to C and then the API always prints None
in the game, but the proper value in the debug command line. After running the error checking for the Python C API, I run these lines first:
PyObject* result = PyRun_String(cPlayerString, Py_eval_input, globalDictionary, localDictionary);
auto str = PyToStr(result);
std::string resString(str.begin(), str.end());;
The code in PyToStr(object)
looks like:
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"";
}
When the return ws
is not an arithmetic value, it prints the resulting code properly to the debug console, but prints no value to the console. My first: check on data types and what is being stored by using cout
lines to see if it's being converted back to the proper C/C++ data type:
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;
This code showed: result string data was null when a Python function was called, but was equivalent to the immediate character value of any arithmetic function. My second was to write the ws
string to a plain text file to make sure that it is even creating the Unicode representation properly:
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();
}
This always writes None followed by a random series of numbers and letters if a Python function such as print
is called, or the immediate arithmetic value of a math computation, followed by I assume Unicode, to the .txt file. I'm unsure whether I need to add another data type conversion to capture the value of ws
regardless of simple arithmetic or a function called, I need to capture the value of ws
in a different way (though I haven't found anything about passing Python Objects through arguments in the API, which would probably be a C thing, or I'm not certain on the syntax to do so), or something else entirely is not gathering the proper data through API calls.
Since this project is my senior capstone project, if I can get the right value to the text file everytime, I think it can be a workaround to make the project work for the parameters of the senior project.
Thanks in advance!