embedding and extending python C API registering callback handlerobjects

T

Tim Spens

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
 
M

Matimus

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,787
Messages
2,569,627
Members
45,329
Latest member
InezZ76898

Latest Threads

Top