Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Calling Python from C | Set 2

  • Last Updated : 27 Mar, 2019

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




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;
}

 
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 :




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

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 :




/* 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);
}

 
Code #4 : Testing the extension function




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

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




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;
    }
    ...

 
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 :




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();
          
    }


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!