Ben Hollier
Ben Hollier

Reputation: 605

Pass std::string into PyObject_CallFunction

When I run pResult = PyObject_CallFunction(pFunc, "s", &"String"), the python script returns the correct string. But, if I try to run this:

std::string passedString = "String";
pResult = PyObject_CallFunction(pFunc, "s", &passedString)

Then convert the pResult into a std::string, I get <NULL> when I print it. Here is some (probably) complete code that returns <NULL>:

C++ Code:

#include <Python.h>
#include <string>
#include <iostream>

int main()
{
    PyObject *pName, *pModule, *pDict, *pFunc;

    // Set PYTHONPATH TO working directory
    setenv("PYTHONPATH",".",1); //This doesn't help
    setenv("PYTHONDONTWRITEBYTECODE", " ", 1);

    // Initialize the Python Interpreter
    Py_Initialize();

    // Build the name object
    pName = PyUnicode_FromString((char*)"string");
    // Load the module object
    pModule = PyImport_Import(pName);
    // pDict is a borrowed reference
    pDict = PyModule_GetDict(pModule);
    // pFunc is also a borrowed reference
    pFunc = PyDict_GetItemString(pDict, (char*)"getString");

    if (pFunc != NULL)
    {
        if (PyCallable_Check(pFunc))
        {
            PyObject *pResult;

            std::string passedString = "String";
            pResult = PyObject_CallFunction(pFunc, "s", &passedString);

            PyObject* pResultStr = PyObject_Repr(pResult);

            std::string returnedString = PyUnicode_AsUTF8(pResultStr);
            std::cout << returnedString << std::endl;

            Py_DECREF(pResult);
            Py_DECREF(pResultStr);
        }
        else {PyErr_Print();}
    }
    else {std::cout << "pFunc is NULL!" << std::endl;}

    // Clean up
    Py_DECREF(pFunc);
    Py_DECREF(pDict);
    Py_DECREF(pModule);
    Py_DECREF(pName);

    // Finish the Python Interpreter
    Py_Finalize();
}

Python Script (string.py):

def getString(returnString):
        return returnString

I'm on Ubuntu (linux) and I'm using Python 3.4

Upvotes: 4

Views: 4544

Answers (1)

Nasser Al-Shawwa
Nasser Al-Shawwa

Reputation: 3663

You should pass a c-style string to PyObject_CallFunction for your code to work. In order to get a c-string from a std::string, use the c_str() method. So the following line:

pResult = PyObject_CallFunction(pFunc, "s", &passedString);

Should look like this:

pResult = PyObject_CallFunction(pFunc, "s", passedString.c_str());

Upvotes: 5

Related Questions