Illegal instruction on layers of callback wrappers
Thomas Stover <[email protected]> Thu, 12 May 2011 18:01:09 -0500
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <[email protected]> |
I finally finished a stripped down example that reproduces the problem.
== glibcallback.c ======
#include <glib.h>
gboolean g_timeout_wrapper(gpointer data)
{
/* explicit type cast from void * to function pointer */
int (*callback) (int) = (int (*) (int)) data;
int x;
g_print("g_timeout_wrapper(): I'm going to call the my callback...\n");
x = callback(5);
g_print("callback returned %d\n", x);
return TRUE;
}
int use_callback( int (*callback) (int) )
{
g_print("use_callback(): wait 3 seconds...\n");
g_timeout_add_seconds(3, g_timeout_wrapper, callback);
return 0;
}
========================
gcc -c -fpic glibcallback.c `pkg-config --cflags glib-2.0`
gcc -shared -Wl-soname,libglibcallback.so.0.1 -o libglibcallback.so.0.0.1
glibcallback.o `pkg-config --libs glib-2.0`
====glibcallback.py================
#!/usr/bin/env python
from sys import *
from ctypes import *
import glib
def CallbackFromPython(y):
print "CallbackFromPython()"
return y + 5
class GlibCallback:
def CallbackWrapper(self, y):
return self.callback_variable(y)
def __init__(self, callback_variable):
cdll.LoadLibrary("libglibcallback.so.0.1")
ctype_object = CDLL("libglibcallback.so.0.1")
set_conversion_mode("utf-8", "strict")
CALLBACK_TYPE = CFUNCTYPE(c_int, c_int)
use_callback = ctype_object.use_callback
use_callback.restype = c_int
use_callback.argtypes = [CALLBACK_TYPE]
callback = CALLBACK_TYPE(self.CallbackWrapper)
use_callback(callback)
self.callback_variable = CallbackFromPython
MainLoop = glib.MainLoop()
Obj = GlibCallback(CallbackFromPython)
MainLoop.run()
===================================
LD_LIBRARY_PATH=./ python ./glibcallback.py
use_callback(): wait 3 seconds...
g_timeout_wrapper(): I'm goint to call the my callback...
Illegal instruction
or some runs: Segmentation fault
====================================
On the other hand it works if you take out the extra python wrapper or
make it not a instance method (correct python terminology?) eg...
def CallbackFromPython(y):
print "CallbackFromPython()"
return y + 5
cdll.LoadLibrary("libglibcallback.so.0.1")
ctype_object = CDLL("libglibcallback.so.0.1")
set_conversion_mode("utf-8", "strict")
CALLBACK_TYPE = CFUNCTYPE(c_int, c_int)
use_callback = ctype_object.use_callback
use_callback.restype = c_int
use_callback.argtypes = [CALLBACK_TYPE]
callback = CALLBACK_TYPE(CallbackFromPython)
MainLoop = glib.MainLoop()
use_callback(callback)
MainLoop.run()
yeilds:
use_callback(): wait 3 seconds...
g_timeout_wrapper(): I'm goint to call the my callback...
CallbackFromPython()
callback returned 10
g_timeout_wrapper(): I'm goint to call the my callback...
CallbackFromPython()
callback returned 10
This can't be a bug. Surely I'm doing something wrong. Ideas?
--
www.thomasstover.com
FLYNN LIVES!
------------------------------------------------------------------------------
Achieve unprecedented app performance and reliability
What every C/C++ and Fortran developer should know.
Learn how Intel has extended the reach of its next-generation tools
to help boost performance applications - inlcuding clusters.
http://p.sf.net/sfu/intel-dev2devmay