Calling Python from C | Set 2

Prerequisite: Calling Python from C | Set 1

A reference to an existing Python callable needs to be passed in, to use this function. To do that there are many ways like – simply writing C code to extract a symbol from an existing module or having a callable object passed into an extension module.

Code #1 : Simple embedding example



filter_none

edit
close

play_arrow

link
brightness_4
code

int main()
{
    PyObject * pow_func;
    double x;
    Py_Initialize();
      
    // Get a reference to the math.pow function
    pow_func = import_name("math", "pow");
      
    // Call it using our call_func() code 
    for (x = 0.0; x < 10.0; x += 0.1)
    {
        printf("% 0.2f % 0.2f\n", x, call_func(pow_func, x, 2.0));
    }
          
    Py_DECREF(pow_func);
    Py_Finalize();
    return 0;
}

chevron_right


 
To build this last example, C needs to be compiled and link against the Python interpreter. The snippet below shows how to do it (this is something that might require some amount of fiddling with on your machine):

Code #2 :

filter_none

edit
close

play_arrow

link
brightness_4
code

all::
cc -g embed.c -I/usr/local/include/python3.3m \
-L /usr/local/lib/python3.3/config-3.3m -lpython3.3m

chevron_right


Compiling and running the resulting executable gives output as :

0.00 0.00
0.10 0.01
0.20 0.04
0.30 0.09
0.40 0.16
...

 
There is another example given by the code below that shows an extension function that receives a callable and some arguments and passes them to call_func() for the purposes of testing.

Code #3 :

filter_none

edit
close

play_arrow

link
brightness_4
code

/* Extension function for testing the C-Python callback */
  
PyObject * py_call_func(PyObject * self, PyObject * args)
{
    PyObject * func;
  
    double x, y, result;
    if (! PyArg_ParseTuple(args, "Odd", &func, &x, &y))
    {
        return NULL;
    }
    result = call_func(func, x, y);
    return Py_BuildValue("d", result);
}

chevron_right


 
Code #4 : Testing the extension function

filter_none

edit
close

play_arrow

link
brightness_4
code

import work
  
def add(x, y):
    return x + y
  
work.call_func(add, 3, 4)

chevron_right


Output :

7.0

 
It is critical that first we need to have a Python object representing the callable that is to be invoked. This could be a function, class, method, built-in method, or anything that implements the __call__() operation. To verify whether it is a callable function use PyCallable_Check().

Code #5 : Checking PyCallable_Check() function

filter_none

edit
close

play_arrow

link
brightness_4
code

double call_func(PyObject *func, double x, double y)
{
    ...
    // Verify that func is a proper callable
    if (!PyCallable_Check(func))
    {
        fprintf(stderr, "call_func: expected a callable\n");
        goto fail;
    }
    ...

chevron_right


 
Simply use PyObject_Call() to call a function, supplying it with the callable object, a tuple of arguments, and an optional dictionary of keyword arguments.

Py_BuildValue() can be used to build the argument tuple or dictionary.

Code #6 :

filter_none

edit
close

play_arrow

link
brightness_4
code

double call_func(PyObject *func, double x, double y)
    {
        PyObject *args;
        PyObject *kwargs;
          
        /* Build arguments */
        args = Py_BuildValue("(dd)", x, y);
        kwargs = NULL;
        /* Call the function */
        result = PyObject_Call(func, args, kwargs);
        Py_DECREF(args);
        Py_XDECREF(kwargs);
         
          
        /* Check for Python exceptions (if any) */
        if (PyErr_Occurred())
        {
            PyErr_Print();
            goto fail;
        }
          
    fail:
        PyGILState_Release(state);
        abort();
          
    }

chevron_right




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.