2

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?

MarcioPorto
  • 555
  • 7
  • 22

1 Answers1

3

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.

tynn
  • 38,113
  • 8
  • 108
  • 143
  • What should I do to store the returned string then? – MarcioPorto Nov 16 '15 at 08:30
  • [PyUnicode_FromObject()](https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_FromObject) might not be useful at all. `pValue` should be a unicode object already. See [Clean Way to Convert Python 3 Unicode to std::string](https://stackoverflow.com/questions/17515467/clean-way-to-convert-python-3-unicode-to-stdstring) for more detail on how to get a c string from the Python unicode object. – tynn Nov 16 '15 at 09:26