2010-10-01 20 views
5

Así que casi termino. Ahora tengo un código de trabajo que llama a la función de devolución de llamada de python.SWIG pasando argumento a la función de devolución de llamada de pitón

Lo único que necesito ahora es cómo pasar el argumento a la función de devolución de llamada de python.

Mi callback.c es:

#include <stdio.h> 

typedef void (*CALLBACK)(void); 
CALLBACK my_callback = 0; 

void set_callback(CALLBACK c); 
void test(void); 

void set_callback(CALLBACK c) { 
    my_callback = c; 
} 

void test(void) { 
    printf("Testing the callback function\n"); 
    if (my_callback) (*my_callback)(); 
    else printf("No callback registered\n"); 
} 

Mi callback.i es:

// An entirely different mechanism for handling a callback 

%module callback 
%{ 
typedef void (*CALLBACK)(void); 
extern CALLBACK my_callback; 

extern void set_callback(CALLBACK c); 
extern void my_set_callback(PyObject *PyFunc); 

extern void test(void); 
%} 

extern CALLBACK my_callback; 

extern void set_callback(CALLBACK c); 
extern void my_set_callback(PyObject *PyFunc); 

extern void test(void); 

%{ 
static PyObject *my_pycallback = NULL; 
static void PythonCallBack(void) 
{ 
    PyObject *func, *arglist; 
    PyObject *result; 

    func = my_pycallback;  /* This is the function .... */ 
    arglist = Py_BuildValue("()"); /* No arguments needed */ 
    result = PyEval_CallObject(func, arglist); 
    Py_DECREF(arglist); 
    Py_XDECREF(result); 
    return /*void*/; 
} 

void my_set_callback(PyObject *PyFunc) 
{ 
    Py_XDECREF(my_pycallback);   /* Dispose of previous callback */ 
    Py_XINCREF(PyFunc);   /* Add a reference to new callback */ 
    my_pycallback = PyFunc;   /* Remember new callback */ 
    set_callback(PythonCallBack); 
} 

%} 

%typemap(python, in) PyObject *PyFunc { 
    if (!PyCallable_Check($input)) { 
     PyErr_SetString(PyExc_TypeError, "Need a callable object!"); 
     return NULL; 
    } 
    $1 = $input; 
} 

Funciona bien. ¿Qué debo hacer para poder pasar el argumento al my_callback? ¡Cualquier ayuda será muy apreciada!

Respuesta

3

Los argumentos para la devolución de llamada son el segundo argumento para PyEval_CallObject(). En este momento está construyendo una tupla vacía, lo que significa "sin argumentos". Entonces, cambia eso. Donde ahora se hace:

arglist = Py_BuildValue("()"); /* No arguments needed */ 

que en lugar de pasar Py_BuildValue sean cuales sean los argumentos que desea que la función de Python para recibir. Por ejemplo, si desea pasar la devolución de llamada de un número entero, una cadena y un objeto de Python que obtuvo de alguna parte, puede hacer:

arglist = Py_BuildValue("(isO)", the_int, the_str, the_pyobject); 
+0

no he incluido las definiciones de the_int, the_str y the_pyobject en mi ejemplo. Serían las cosas * que * quieres pasar. Es un ejemplo. –

+0

Oh .. Necesito hacer static void PythonCallBack (char * the_str) también. ¡Funcionó! Muchas gracias! – joon

Cuestiones relacionadas