Llamar a Python desde C | conjunto 2

Requisito previo: llamar a Python desde C | Serie 1

Se debe pasar una referencia a un Python invocable existente para usar esta función. Para hacerlo, hay muchas maneras, como simplemente escribir código C para extraer un símbolo de un módulo existente o pasar un objeto invocable a un módulo de extensión.

Código n.º 1: ejemplo de incrustación simple

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

 
Para construir este último ejemplo, C debe compilarse y vincularse con el intérprete de Python. El fragmento a continuación muestra cómo hacerlo (esto es algo que podría requerir cierta cantidad de manipulación en su máquina):

Código #2:

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

Compilar y ejecutar el ejecutable resultante da como resultado:

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

 
Hay otro ejemplo dado por el código a continuación que muestra una función de extensión que recibe un invocable y algunos argumentos y los pasa call_func()para fines de prueba.

Código #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);
}

 
Código #4: Probando la función de extensión

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

Producción :

7.0

 
Es fundamental que primero necesitemos tener un objeto de Python que represente el invocable que se va a invocar. Esto podría ser una función, clase, método, método incorporado o cualquier cosa que implemente la __call__() operación. Para verificar si es una función invocable, use PyCallable_Check().

Código #5: PyCallable_Check()función de verificación

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

 
Simplemente use PyObject_Call()para llamar a una función, proporcionándole el objeto invocable, una tupla de argumentos y un diccionario opcional de argumentos de palabras clave.

Py_BuildValue() se puede utilizar para construir la tupla de argumento o el diccionario.

Código #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();
          
    }

Publicación traducida automáticamente

Artículo escrito por manikachandna97 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *