embedding and extending python C API registering callback handlerobjects

Discussion in 'Python' started by Tim Spens, Jun 27, 2008.

  1. Tim Spens

    Tim Spens Guest

    Hello all,

    I've been trying to get an example found here http://codeidol.com/python/python3/Embedding-Python/Registering-Callback-Handler-Objects/
    to work. Every thing works fine except when I try to trigger an event from c that will call a python function. Here is my test code:

    //-----------------------python code--------------------------//
    #! /usr/bin/env python
    import time
    import callback

    def callback1(label,count):
    print 'callback1 successfully triggered from python via callback.so'
    return 'callback1 => %s number %i' % (label, count)

    def callback2(label,count):
    return 'callback2 => ' + label * count

    print '\nTest1:'
    callback.setHandler(callback1)
    callback.triggerEvent() # simulate events caught by C layer

    print '\nTest2:'
    callback.setHandler(callback2)

    print 'Waiting for callback2 to be called from c:'
    while 1:
    time.sleep(.001)

    //-----------------------c code-------------------------------//
    #include <Python.h>
    #include <stdlib.h>

    /* keep Python object in C */
    static PyObject *Handler = NULL;

    void Route_Event(char *label, int count){
    char *cres;
    PyObject *args, *pres;
    /* call Python handler */
    args = Py_BuildValue("(si)", label, count);
    pres = PyEval_CallObject(Handler, args);
    Py_DECREF(args);
    if (pres != NULL){
    /* use and decref handler result */
    PyArg_Parse(pres, "s", &cres);
    printf("%s\n", cres);
    Py_DECREF(pres);
    }}

    // the actual python callback call
    static PyObject *
    make_call(PyObject *function, PyObject *args){
    if (function == NULL) return NULL;
    PyObject * val = PyObject_CallObject(function, args);
    Py_XDECREF(args);
    return val;
    }

    static PyObject *
    Register_Handler(PyObject *self, PyObject *args){
    /* save Python callable object */
    Py_XDECREF(Handler);
    PyArg_Parse(args, "O", &Handler);
    Py_XINCREF(Handler);
    Py_INCREF(Py_None);
    return Py_None;
    }

    static PyObject *
    Trigger_Event(PyObject *self, PyObject *args){
    /* let Python simulate event caught by C */
    static int count = 0;
    Route_Event("spam", count++);
    Py_INCREF(Py_None);
    return Py_None;
    }

    static struct PyMethodDef callback_methods[] = {
    {"setHandler", Register_Handler}, /* name, address */
    {"triggerEvent", Trigger_Event},
    {NULL, NULL}
    };
    /* on first "import callback" */
    void initcallback(){ /* this is called by Python */
    (void) Py_InitModule("callback", callback_methods);
    }

    int main(){
    while (1){
    printf("1\n");
    //attempting to call callback2 which is registered to Handler
    //i've also tried args = Py_BuildValue("(si)", label, count); here but I get a segfault.
    PyObject *args = Py_BuildValue("s","c code");
    printf("2\n");
    PyObject* val = make_call(Handler,args);
    printf("3\n");
    Py_XDECREF (val);
    printf("4\n");
    sleep(1);
    }}

    //------------------------compiler stuff----------------------//
    gcc callback.c -c -g -Wall -fpic -I /usr/include/python2.5 -o callback.o
    gcc callback.c -g -Wall -I /usr/include/python2.5 -L /usr/local/lib -lpython2.5 -o callback
    gcc -shared -Wall callback.o -o callback.so

    //------------------------test code results-------------------//
    .../callback.py
    Test1:
    callback1 successfully triggered from python via callback.so
    callback1 => spam number 0

    Test2:
    Waiting for callback2 to be called from c:
    #NOTHING EVER GETS PRINTED HERE CALLBACK NEVER GETS CALLED?

    .../callback
    1
    2
    3
    4
    .....

    Thanks,
    Tim
     
    Tim Spens, Jun 27, 2008
    #1
    1. Advertising

  2. Tim Spens

    Matimus Guest

    On Jun 27, 8:22 am, Tim Spens <> wrote:
    > Hello all,
    >
    > I've been trying to get an example found herehttp://codeidol.com/python/python3/Embedding-Python/Registering-Callb...
    > to work.  Every thing works fine except when I try to trigger an event from c that will call a python function.  Here is my test code:
    >
    > //-----------------------python code--------------------------//
    > #! /usr/bin/env python
    > import time
    > import callback
    >
    > def callback1(label,count):
    >         print 'callback1 successfully triggered from python via callback.so'
    >         return 'callback1 => %s number %i' % (label, count)
    >
    > def callback2(label,count):
    >         return 'callback2 => ' +  label * count
    >
    > print '\nTest1:'
    > callback.setHandler(callback1)
    > callback.triggerEvent()         # simulate events caught by C layer
    >
    > print '\nTest2:'
    > callback.setHandler(callback2)
    >
    > print 'Waiting for callback2 to be called from c:'
    > while 1:
    >         time.sleep(.001)
    >
    > //-----------------------c code-------------------------------//
    > #include <Python.h>
    > #include <stdlib.h>
    >
    > /* keep Python object in C */
    > static PyObject *Handler = NULL;
    >
    > void Route_Event(char *label, int count){
    >     char *cres;
    >     PyObject *args, *pres;
    >     /* call Python handler */
    >     args = Py_BuildValue("(si)", label, count);
    >     pres = PyEval_CallObject(Handler, args);
    >     Py_DECREF(args);
    >     if (pres != NULL){
    >         /* use and decref handler result */
    >         PyArg_Parse(pres, "s", &cres);
    >         printf("%s\n", cres);
    >         Py_DECREF(pres);
    >
    > }}
    >
    > // the actual python callback call
    > static PyObject *
    > make_call(PyObject *function, PyObject *args){
    >     if (function == NULL) return NULL;
    >     PyObject * val = PyObject_CallObject(function, args);
    >     Py_XDECREF(args);
    >     return val;
    >
    > }
    >
    > static PyObject *
    > Register_Handler(PyObject *self, PyObject *args){
    >     /* save Python callable object */
    >     Py_XDECREF(Handler);
    >     PyArg_Parse(args, "O", &Handler);
    >     Py_XINCREF(Handler);
    >     Py_INCREF(Py_None);
    >     return Py_None;
    >
    > }
    >
    > static PyObject *
    > Trigger_Event(PyObject *self, PyObject *args){
    >     /* let Python simulate event caught by C */
    >     static int count = 0;
    >     Route_Event("spam", count++);
    >     Py_INCREF(Py_None);
    >     return Py_None;
    >
    > }
    >
    > static struct PyMethodDef callback_methods[] = {
    >     {"setHandler",    Register_Handler},       /* name, address */
    >     {"triggerEvent",  Trigger_Event},
    >     {NULL, NULL}};
    >
    >                                       /* on first "import callback" */
    > void initcallback(){                  /* this is called by Python  */
    >     (void) Py_InitModule("callback", callback_methods);
    >
    > }
    >
    > int main(){
    >         while (1){
    >                 printf("1\n");
    >                 //attempting to call callback2 which is registered to Handler
    >                 //i've also tried args = Py_BuildValue("(si)", label, count); here but I get a segfault.
    >                 PyObject *args = Py_BuildValue("s","c code");
    >                 printf("2\n");
    >                 PyObject* val = make_call(Handler,args);
    >                 printf("3\n");
    >             Py_XDECREF (val);
    >             printf("4\n");
    >                 sleep(1);
    >
    > }}
    >
    > //------------------------compiler stuff----------------------//
    > gcc callback.c -c -g -Wall -fpic -I /usr/include/python2.5 -o callback.o
    > gcc callback.c -g -Wall -I /usr/include/python2.5 -L /usr/local/lib -lpython2.5 -o callback
    > gcc -shared -Wall callback.o -o callback.so
    >
    > //------------------------test code results-------------------//
    > ../callback.py
    > Test1:
    > callback1 successfully triggered from python via callback.so
    > callback1 => spam number 0
    >
    > Test2:
    > Waiting for callback2 to be called from c:
    > #NOTHING EVER GETS PRINTED HERE CALLBACK NEVER GETS CALLED?
    >
    > ../callback
    > 1
    > 2
    > 3
    > 4
    > ....
    >
    > Thanks,
    > Tim


    Maybe you just need to flush the stdout buffer in python.
    `sys.stdout.flush()`

    Matt
     
    Matimus, Jun 27, 2008
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luke
    Replies:
    3
    Views:
    532
    Robin Becker
    Oct 24, 2003
  2. Faheem Mitha
    Replies:
    0
    Views:
    441
    Faheem Mitha
    Jun 28, 2004
  3. stefan
    Replies:
    3
    Views:
    450
    stefan
    Dec 8, 2004
  4. Juan T. Llibre
    Replies:
    2
    Views:
    4,061
    =?Utf-8?B?UmljaA==?=
    Dec 16, 2006
  5. Michael Kipper

    Registering a GLUT Callback in C++

    Michael Kipper, Jan 4, 2006, in forum: C++
    Replies:
    5
    Views:
    3,417
    Manuel
    Jan 5, 2006
Loading...

Share This Page