Calling Python from C | Set 2

Python Methods and Functions

A reference to an existing Python callable must be passed in order to use this function. There are many ways to do this, such as — just write C code to extract a symbol from an existing module or pass a callable to a plugin.

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 this using our call_func () code

  for (x = 0.0; x & lt; 10.0; x + = 0.1)

{

printf ( "% 0.2f% 0.2f " , x, call_func (pow_func, x, 2.0)); 

}

 

  Py_DECREF (pow_func); 

Py_Finalize (); 

return 0; 

}

To build this final example, C needs to be compiled and linked with a Python interpreter. Below is a code snippet showing how to do this (this is something that might take some effort on your computer):

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

Below is another example, provided by the code below which shows an extension function that receives a callable and some arguments and sends them to call_func() for testing purposes.

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" , & amp; func, & amp; x, & amp; 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 

we had a Python object representing the callable object to be called. It can be a function, class, method, inline method, or anything that implements __call__() . To check if it is a callable function, use PyCallable_Check() .

Code # 5: Function check PyCallable_Check ()

double call_func (PyObject * func, double x, double y)

{

...

// Check that func is called correctly

if (! PyCallable_Check (func))

{

  fprintf (stderr, "call_func : expected a callable " ); 

goto fail; 

}

...

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

Py_BuildValue() can be used to create an 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; 

/ * Function call * /

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

 

}





Get Solution for free from DataCamp guru