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?

7
  • 1
    What do you mean with "it seems like the PyUnicode_FromString() method doesn't work anymore"? Are you getting an exception? A segfault? Something else? Commented Nov 15, 2015 at 17:59
  • I meant PyString_FromString(). My bad. Commented Nov 16, 2015 at 0:58
  • There's no such thing as PyString_FromString in Python 3. Commented Nov 16, 2015 at 8:36
  • 1
    Have you considered using an existing wrapper library like Boost.Python instead of the low-level C API? It should make these things much simpler. That said, please read the guidelines here, your question is by definition off-topic, as explained there. Commented Nov 16, 2015 at 9:13
  • 1
    and there's also PyUnicode_AsUTF8 if you really want a string Commented Nov 16, 2015 at 9:34

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

What should I do to store the returned string then?
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 for more detail on how to get a c string from the Python unicode object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.