Skip to content
Related Articles

Related Articles

Calling Python from C | Set 1
  • Last Updated : 27 Mar, 2019

In this article, we will mainly focus on safe execution of a Python callable from C, returning a result back to C and writing C code that needs to access a Python function as a callback.

The code below focuses on the tricky parts that are involved in calling Python from C.

Code #1 : [Step 1 and 2] Own the GIL and Verify that function is a proper callable




#include <Python.h>
  
/* Execute func(x, y) in the Python interpreter. The
arguments and return result of the function must
be Python floats */
  
double call_func(PyObject *func, double x, double y)
{
    PyObject *args;
    PyObject *kwargs;
    PyObject *result = 0;
    double retval;
      
    // Make sure we own the GIL
    PyGILState_STATE state = PyGILState_Ensure();
      
      
    // Verify that func is a proper callable
    if (!PyCallable_Check(func))
    {
        fprintf(stderr, "call_func: expected a callable\n");
        goto fail;
    }

 
Code #2 : Building Arguments, calling function, Check for Python exceptions

Create the return value, Restore previous GIL state and return.






    // Step3
    args = Py_BuildValue("(dd)", x, y);
    kwargs = NULL;
      
    // Step 4
    result = PyObject_Call(func, args, kwargs);
    Py_DECREF(args);
    Py_XDECREF(kwargs);
      
    // Step 5
    if (PyErr_Occurred())
    {
        PyErr_Print();
        goto fail;
    }
      
    // Verify the result is a float object 
    if (!PyFloat_Check(result))
    {
        fprintf(stderr, "call_func: callable didn't return a float\n");
        goto fail;
    }
      
    // Step 6
    retval = PyFloat_AsDouble(result);
    Py_DECREF(result);
      
    // Step 7
    PyGILState_Release(state);
    return retval;
    fail:
        Py_XDECREF(result);
        PyGILState_Release(state);
        abort(); 
}

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.
 
The code given below shows calling a function from an embedded Python interpreter.

Code #3 : Loading a symbol from a module




#include <Python.h>
/* Definition of call_func() same as above */
  
/* Load a symbol from a module */
PyObject *import_name(const char *modname, const char *symbol)
{
    PyObject *u_name, *module;
    u_name = PyUnicode_FromString(modname);
    module = PyImport_Import(u_name);
    Py_DECREF(u_name);
      
    return PyObject_GetAttrString(module, symbol);
}

 Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.  

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course. And to begin with your Machine Learning Journey, join the Machine Learning – Basic Level Course

My Personal Notes arrow_drop_up
Recommended Articles
Page :