simplest c python api callback example

Tim Spens t_spens at yahoo.com
Thu Jun 26 21:15:13 CEST 2008


The following is a simple complete example using the c python api to generate callbacks from c to python.  But when I run the c code I get a segfault in PyInt_FromLong () (see below).  Most of this example code was taken from pg 1478 of the 3rd edition python o'reilly book.  I cannot see what I'm doing wrong here to get this segfault?  Please help.

//-------------------python-code-------------------------//
#! /usr/bin/env python
#######################################################
# register for and handle event callbacks from C;
# compile C code, and run with 'python register.py'
#######################################################

import time

#
# C calls these Python functions;
# handle an event, return a result
#
def callback1(label, count):
    return 'callback1 called with args: label-%s and count-%i' % (label, count)
#
# Python calls a C extension module
# to register handlers, trigger events
#

import cregister
cregister.setpythonHandler(callback1)

print '\nwaiting for callback pythonHandler to be called:'
while 1:
	time.sleep(1)

//-------------------compiler commands--------------//
gcc -Wall -fno-strict-aliasing -g -I /usr/include/python2.5 -c cregister.c;gcc -g -Wall -I /usr/include/python2.5 -L /usr/local/lib -lpython2.5 cregister.c -o cregister;gcc -shared -fPIC -g -Wall -I /usr/include/python2.5 -L /usr/lib -lpython2.5 -o cregister.so cregister.o

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

/***********************************************/
/* 1) code to route events to Python object    */
/* note that we could run strings here instead */
/***********************************************/

//python handlers
//keep Python object in C
static PyObject *pythonHandler = NULL;

void Route_Event(){
    PyObject *args;
    // call Python handler
    args = Py_BuildValue("(si)", "c code", 5);
    PyEval_CallObject(pythonHandler, args);
}

/*****************************************************/
/* 2) python extension module to register handlers   */
/* python imports this module to set handler objects */
/*****************************************************/
static PyObject *
Register_pythonHandler(PyObject *self, PyObject *args){
    // save Python callable object
    Py_XDECREF(pythonHandler);                 //called before?
    PyArg_Parse(args, "O", &pythonHandler);    //one argument?
    Py_XINCREF(pythonHandler);                 //add a reference
    Py_INCREF(Py_None);                        //return 'None': success
    return Py_None;
}

//makes these functions available by importing cregister in python
static struct PyMethodDef cregister_methods[] = {
    {"setpythonHandler",    Register_pythonHandler},
    {NULL, NULL}
};

// this is called by Python on first "import cregister"
void initcregister(){
    (void) Py_InitModule("cregister", cregister_methods);
}

int main(){
	while (1){
	    PyObject *arglist;
		arglist = Py_BuildValue("(si)", "c code", 5);
		Py_XINCREF(pythonHandler);
		Py_XINCREF(arglist);
		PyEval_CallObject(pythonHandler, arglist);
		Py_XDECREF(pythonHandler);
		Py_XDECREF(arglist);
		sleep(1);
	}
}

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7c1c6b0 (LWP 13699)]
0xb7e0bcfb in PyInt_FromLong () from /usr/lib/libpython2.5.so.1.0
(gdb) bt
#0  0xb7e0bcfb in PyInt_FromLong () from /usr/lib/libpython2.5.so.1.0
#1  0xb7e8cae6 in ?? () from /usr/lib/libpython2.5.so.1.0
#2  0x00000005 in ?? ()
#3  0x00000006 in ?? ()
#4  0xbf89a378 in ?? ()
#5  0xb7e9d095 in _PyObject_GC_Malloc () from /usr/lib/libpython2.5.so.1.0
#6  0xb7e8d1dd in ?? () from /usr/lib/libpython2.5.so.1.0
#7  0x00000002 in ?? ()
#8  0x08048320 in ?? ()
#9  0x72d6dafa in ?? ()
#10 0x00000029 in ?? ()
#11 0xbf89a474 in ?? ()
#12 0xbf89a478 in ?? ()
#13 0x00000000 in ?? ()



      




More information about the Python-list mailing list