0

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!

  • I think you may be misunderstanding `print`. It writes text to some "file" (by default `sys.stdout`) but returns `None`, and therefore `None` is what you can capture in C. Load a Python terminal and try `result = print("Something")` and see what `result` is.... – DavidW Nov 03 '19 at 17:36
  • Does this answer your question? [How To catch python stdout in c++ code](https://stackoverflow.com/questions/4307187/how-to-catch-python-stdout-in-c-code) – DavidW Nov 03 '19 at 17:37
  • 1
    I've suggested a duplicate based on my understanding of your question. It's possible I've missed the point, in which case I can retract the duplicate vote. Here's a Python 3 version too: https://stackoverflow.com/questions/46632488/how-to-catch-python-3-stdout-in-c-code – DavidW Nov 03 '19 at 17:38

0 Answers0