MarcioPorto
MarcioPorto

Reputation: 565

Python 3: Python/C API String Problems

I am trying to use the Python/C API to run a Python function which returns a string. I want to store that returned string to a C++ variable, but I can't get it to work. I am using Python 3 and it seems like the PyString_FromString() method doesn't work anymore. Here is my code:

int main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pDict, *pFunc, *pValue;

    Py_Initialize();

    pName = PyUnicode_FromString("ocr");

    pModule = PyImport_Import(pName);

    pDict = PyModule_GetDict(pModule);

    pFunc = PyDict_GetItemString(pDict, "get_text");

    pValue = PyUnicode_FromString("ocr_noise.png");
    pValue = PyObject_CallObject(pFunc, pValue);

    std::string result = PyUnicode_FromObject(pValue);

    Py_DECREF(pModule);
    Py_DECREF(pName);
    Py_DECREF(pValue);

    Py_Finalize();

    return 0;
}

The python file is called ocr.py, and the function I am trying to call is called get_text(value). I am trying to pass in "ocr_noise.png" as an argument. Any ideas what I should do?

EDIT 2: I don't need to use std::string as in the code. What else can I use to store the string returned from the function?

Upvotes: 2

Views: 4754

Answers (1)

tynn
tynn

Reputation: 39853

It's essential to check the return values of all Python functions. Python returns a nullptr if there was an error. So PyUnicode_FromString() works fine in your code. It just segfaults because pValue is a nullptr you got from PyObject_CallObject(). Putting PyErr_Print() just after this call prints:

TypeError: argument list must be a tuple

You need to pass a tuple of objects as argument, not a single str. Instead you might want to use PyObject_CallFunction(pFunc, "O", pValue) or PyObject_CallFunction(pFunc, "s", "ocr_noise.png").

Additionally have a look into PyImport_ImportModule(). Furthermore

std::string result = PyUnicode_FromObject(pValue);

should not even compile since it returns a PyObject * not a string.

Upvotes: 3

Related Questions