Calling a python method from C/C++, and extracting its return value Calling a python method from C/C++, and extracting its return value python python

Calling a python method from C/C++, and extracting its return value


As explained before, using PyRun_SimpleString seems to be a bad idea.

You should definitely use the methods provided by the C-API (http://docs.python.org/c-api/).

Reading the introduction is the first thing to do to understand the way it works.

First, you have to learn about PyObject that is the basic object for the C API. It can represent any kind of python basic types (string, float, int,...).

Many functions exist to convert for example python string to char* or PyFloat to double.

First, import your module :

PyObject* myModuleString = PyString_FromString((char*)"mytest");PyObject* myModule = PyImport_Import(myModuleString);

Then getting a reference to your function :

PyObject* myFunction = PyObject_GetAttrString(myModule,(char*)"myabs");PyObject* args = PyTuple_Pack(1,PyFloat_FromDouble(2.0));

Then getting your result :

PyObject* myResult = PyObject_CallObject(myFunction, args)

And getting back to a double :

double result = PyFloat_AsDouble(myResult);

You should obviously check the errors (cf. link given by Mark Tolonen).

If you have any question, don't hesitate. Good luck.


Here is a sample code I wrote (with the help of various online sources) to send a string to a Python code, then return a value.

Here is the C code call_function.c:

#include <Python.h>#include <stdlib.h>int main(){   // Set PYTHONPATH TO working directory   setenv("PYTHONPATH",".",1);   PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *presult;   // Initialize the Python Interpreter   Py_Initialize();   // Build the name object   pName = PyString_FromString((char*)"arbName");   // 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*)"someFunction");   if (PyCallable_Check(pFunc))   {       pValue=Py_BuildValue("(z)",(char*)"something");       PyErr_Print();       printf("Let's give this a shot!\n");       presult=PyObject_CallObject(pFunc,pValue);       PyErr_Print();   } else    {       PyErr_Print();   }   printf("Result is %d\n",PyInt_AsLong(presult));   Py_DECREF(pValue);   // Clean up   Py_DECREF(pModule);   Py_DECREF(pName);   // Finish the Python Interpreter   Py_Finalize();    return 0;}

Here is the Python code, in file arbName.py:

 def someFunction(text):    print 'You passed this Python program '+text+' from C! Congratulations!'    return 12345

I use the command gcc call_function.c -I/usr/include/python2.6 -lpython2.6 ; ./a.out to run this process. I'm on redhat. I recommend using PyErr_Print(); for error checking.


A complete example of calling a Python function and retrieving the result is located at http://docs.python.org/release/2.6.5/extending/embedding.html#pure-embedding:

#include <Python.h>intmain(int argc, char *argv[]){    PyObject *pName, *pModule, *pDict, *pFunc;    PyObject *pArgs, *pValue;    int i;    if (argc < 3) {        fprintf(stderr,"Usage: call pythonfile funcname [args]\n");        return 1;    }    Py_Initialize();    pName = PyString_FromString(argv[1]);    /* Error checking of pName left out */    pModule = PyImport_Import(pName);    Py_DECREF(pName);    if (pModule != NULL) {        pFunc = PyObject_GetAttrString(pModule, argv[2]);        /* pFunc is a new reference */        if (pFunc && PyCallable_Check(pFunc)) {            pArgs = PyTuple_New(argc - 3);            for (i = 0; i < argc - 3; ++i) {                pValue = PyInt_FromLong(atoi(argv[i + 3]));                if (!pValue) {                    Py_DECREF(pArgs);                    Py_DECREF(pModule);                    fprintf(stderr, "Cannot convert argument\n");                    return 1;                }                /* pValue reference stolen here: */                PyTuple_SetItem(pArgs, i, pValue);            }            pValue = PyObject_CallObject(pFunc, pArgs);            Py_DECREF(pArgs);            if (pValue != NULL) {                printf("Result of call: %ld\n", PyInt_AsLong(pValue));                Py_DECREF(pValue);            }            else {                Py_DECREF(pFunc);                Py_DECREF(pModule);                PyErr_Print();                fprintf(stderr,"Call failed\n");                return 1;            }        }        else {            if (PyErr_Occurred())                PyErr_Print();            fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);        }        Py_XDECREF(pFunc);        Py_DECREF(pModule);    }    else {        PyErr_Print();        fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);        return 1;    }    Py_Finalize();    return 0;}