c++pythoncpython-c-apipython-embedding

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


I'd like to call a custom function that is defined in a Python module from C. I have some preliminary code to do that, but it just prints the output to stdout.

mytest.py

import math

def myabs(x):
    return math.fabs(x)

test.cpp

#include <Python.h>

int main() {
    Py_Initialize();
    PyRun_SimpleString("import sys; sys.path.append('.')");
    PyRun_SimpleString("import mytest;");
    PyRun_SimpleString("print mytest.myabs(2.0)");
    Py_Finalize();

    return 0;
}

How can I extract the return value into a C double and use it in C?


Solution

  • 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.