embedding and extending python C API registering callback handler objects
Matimus
mccredie at gmail.com
Fri Jun 27 12:03:05 EDT 2008
On Jun 27, 8:22 am, Tim Spens <t_sp... at yahoo.com> 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
More information about the Python-list
mailing list