Re: Type-safe G_CALLBACK
- From: Zhenghui Zhou <zhouzhenghui gmail com>
- To: gtk-devel-list gnome org
- Subject: Re: Type-safe G_CALLBACK
- Date: Sat, 19 Mar 2011 13:04:07 +0800
For type-safety and light callback, someone may be interesting about this.
Once a time, I worked out a prototype when I need the signal-slot
mechanism in my embedded environment.Please take a look at
https://code.google.com/p/c-sigslot/downloads/list.
The implementation is based on standard longjmp and "stack-frame copy"
technical. So it's 100% type-safety and no marshal needed.
Although it is not 100% portable, I think it works on most stack-based
system. Since there are just a few lines of assemble code for
perticular circumstances, it is easy to port to a special system. The
unknown compiler implemention is pure ANSI C compliant, but it is
based on a hack inside the jmpbuf structure. The comptibility can be
improved by the posix setcontext/getcontext specification.
It is not suitable for large project since you should specify a enough size
of stack-frame for each function or each compilation unit(on header of
the C source file), or a enough size for global scope. I think it can
be eliminated through a modification of the compiler.
The invoke interface can also be improved if C99 variadic macros
present, so that we can use a unified SIGNAL(...) declaration instead
of SIGNAL1(v1), SIGNAL2(v1, v2), etc.
All of the work I would like to accomplish if I have enough time.
Nowadays I'm working hard to port the Tristan's GtkCellArea
implementation to gtk+ 2.x, to make it running under my old
framebuffer base system. I also want to make a framebuffer backend for
the new GTK. I feel a little sorry for that there are few chinese
afford in public community since we have to struggle for better living
and fight against our companions day after day.
2011/3/18 David Zeuthen <zeuthen gmail com>:
> Hey,
>
> Is there any reason we don't have something similar to
> G_DEFINE_CALLBACK() as described below in [1]? It seems like it would
> increase type-safety a lot...
>
> Thanks,
> David
>
> [1] : See [2] for compiler output
>
> #include <gio/gio.h>
>
> /**
> * G_DEFINE_CALLBACK:
> * @function: The function to check
> * @function_type: The expected type of @function.
> *
> * Helper macro to define type-safe callback macros on modern
> * compilers. On older compilers, this just uses the generic
> * G_CALLBACK() macro.
> *
> * In addition to using this for all callback functions, you should
> * use this for every signal in a type. For example, for the
> * #GVolumeMonitor::drive-connected signal it would be used this way
> *
> * <programlisting>
> * #define G_VOLUME_MONITOR_DRIVE_CONNECTED_CALLBACK(f,
> user_data_type) (G_DEFINE_CALLBACK(f, void (*)(GVolumeMonitor*,
> GDrive*, user_data_type)))
> * </programlisting>
> *
> * so the user can use to define a callback for the signal
> *
> * <programlisting>
> * g_signal_connect (volume_monitor,
> * "drive-connected",
> * G_VOLUME_MONITOR_DRIVE_CONNECTED_CALLBACK
> (on_drive_connected, gpointer),
> * NULL);
> * </programlisting>
> *
> * and get a compile-time warning if the on_drive_connected() callback
> * is not of the right type.
> *
> * Since: 2.30
> */
> #if __GNUC__ >= 4
> # define G_DEFINE_CALLBACK(function, function_type)
> (__builtin_choose_expr (__builtin_types_compatible_p (typeof
> (&function), function_type), G_CALLBACK (function), function))
> #else /* __GNUC__ >= 4 */
> # define G_DEFINE_CALLBACK(functoin, function_type) G_CALLBACK (function)
> #endif /* __GNUC__ >= 4 */
>
>
> #define G_VOLUME_MONITOR_DRIVE_CONNECTED_CALLBACK(function,
> user_data_type) (G_DEFINE_CALLBACK(function, void (*)(GVolumeMonitor*,
> GDrive*, user_data_type)))
>
> static void
> on_drive_connected (GVolumeMonitor *monitor,
> GDrive *drive,
> gpointer user_data)
> {
> }
>
> static void
> on_drive_connected_wrong_type (GVolumeMonitor *monitor,
> GDrive *drive,
> gint foo,
> gpointer user_data)
> {
> }
>
> int
> main (int argc, char *argv[])
> {
> GVolumeMonitor *monitor;
>
> g_type_init ();
>
> monitor = g_volume_monitor_get ();
> g_signal_connect (monitor,
> "drive-connected",
> G_VOLUME_MONITOR_DRIVE_CONNECTED_CALLBACK
> (on_drive_connected, gpointer),
> NULL);
>
> g_signal_connect (monitor,
> "drive-connected",
> G_VOLUME_MONITOR_DRIVE_CONNECTED_CALLBACK
> (on_drive_connected_wrong_type, gpointer),
> NULL);
>
> return 0;
> }
>
> [2] : Compiler output from compiling the program in [1] - this is with
> gcc version 4.6.0 20110315 (Red Hat 4.6.0-0.13) (GCC) from Fedora 15
>
> gcc -o foo foo.c `pkg-config --cflags --libs gio-2.0`
> foo.c: In function ‘main’:
> foo.c:72:3: warning: passing argument 3 of
> ‘g_signal_connect_data’ from incompatible pointer type [enabled by
> default]
> /usr/include/glib-2.0/gobject/gsignal.h:350:9: note: expected
> ‘GCallback’ but argument is of type ‘void (*)(struct
> GVolumeMonitor *, struct GDrive *, gint, void *)’
>
> As you can see the compiler complains about callbacks, in this case
> on_drive_connected_wrong_type(), being the wrong type...
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-devel-list
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]