guidod


Documents
-(personal info)
-pTA study
-largefile *
-AutoFS howto
-Geschichte der Informatik
 
(* other webserver)

Bigger Projects
-PFE*
-AC-Archive*
-ZZIPlib *
-XML/G
-C.L.F.R. *
-XM Tool *
 
Smaller Projects
-errno(1)
-glib-man
-gstdint *
... (patches)
-wine-vol-a
 

Older Projects
-MPEG split *
-XFCE *
-htm1-pp
-cc-headers
-runso
-substruct-c
-submorph-c
... (patches)
-xwpe
-xfce 3
 

Download Area *
Sourceforge Project
freespace.sf.net Home
 

sourceforge.net

generated
(C) Guido Draheim
guidod@gmx.de

 

CCheaders

  Make C++ bindings for object-oriented C-libraries like GTK+ but without creating a wrapper library. Best suited for GTK/RAD. (make your first shot of a gtk implemenation with it...)

Introduction

The CCheaders is a small perl-skript that transforms header-files that look like those from the GTK+ system. These are object-oriented declarations written in plain C. For any C header source the output of CCheaders works just like the original because the CCheaders will only add a few lines inside #ifdef __cplusplus. The additions are just some C++ inline-methods inside the structure declarations, and the use of the C++ inclusion/inheritance syntax for the base type of each of the structures (again #ifdef __cplusplus).

As a result, the enhenced (GTK+) headers are much more easier to use from C++. For the one thing, a C++ compiler does know now about the inheritance relations for the structures, so you can leave off the ubiquitous big-caps cast-macros - instead you will benefit from compile-time type-checking as is builtin each C++ compiler.

For the other thing, you can use the (GTK+) procedures as inlined methods along the defined objects. Your code will become much shorter - and in consequence more readable and maintainable. And you don't have to think about which base-type had been introducing the set_border_width method - you can just call the method of that object instance (or their class-scope static-declared counterpart that is also generated).

Unlike real C++ wrappers, like GTK--,, the object size will not increase by a single byte. No additional library needs to be linked in, so even the runtime footprint is the same. And if you don't have a C++ compiler at hand (huh?), you can start rewriting the C++ code in an incremental way because the methods are directly derived from their underlying C-language procedure names. Since the very same headers can be used with a C compiler you will end up at just changing the file extension and it will compile cleanly.

If you want to add another function you can always switch back to C++ mode, make a RAD implementation, and if you're done you can rewrite it back into plain C. Nothing could be easier. It does help me a lot in my GTK developments - and I don't need a real wrapper bloatware (for C++/GTK or even Perl/GTK).

Invokation

The CCheaders is nothing more than a simple perl skript that should be run in the include-base directory of the GTK+ headers. It will then create subdirectories named .cc and put all the transformed headers in there. It will even change the inclusions from <gtk/*.h> to <gtk/cc/*.h> in the touched files.

So what you want to do is

make-cc-headers.pl -q glib.h gdk/*.h gtk/*.h
where the "-q" options means quiet. There are some other (not yet documented) options, just look into the source and try for yourself. This is currently nothing more than a quick hack which serves me well in my GTK developments.

The script can probably be adapted to other C-language object-oriented library systems - apart from two points the script does not make any other assumption on the headers, well other than the naming scheme should be similar to that as used by GTK.

The Makefile that comes with the distribution does have a sys-gtk target that will make-cc your gtk's installed headers. However it will only put C++ extensions into glib and gtk. The gdk has seperated gtktypes and gdkdefs a bit unwisely for this script. If you still want to have C++ extensions for gdk, well, then you could try the target tweak-gdk first (or tweak-gtk to run CCheaders directly thereafter). new: the last version of CCheaders has been trying to declare a bit more in gdktypes.h, some of them need typedefs from gdkprivate.h. But gdkprivate.h is already including gdktypes.h beforehand. And so, the tweak-gdk target is not enough anymore. Sorry.

Try then the examples target on the supplied C++ sources that are derivatives from the GTK+ manual.

Download

You can get the latest tarball from here, it is called sth. like pub/cc-headers-preMMDD.tar.gz. Check out the latest snapshot in the local
public directory.

The latest skript itself is hopefully uploaded as make-cc-headers.pl so you can have a first look.

The Changelog is here just as well.

The latest stable release version is 0.2, the file is at
- both these tarfiles include this html-text.

Example

From GTK+ Tutorial Example 3 (shortened, no comments here)
int main(int argc, char *argv[] )
{
  GtkWidget *window;
  GtkWidget *button;
  GtkWidget *box1;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Hello Buttons!");
  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
                      GTK_SIGNAL_FUNC (delete_event), NULL);
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);

  box1 = gtk_hbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (window), box1);

  button = gtk_button_new_with_label ("Button 1");
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");
  gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0);
  gtk_widget_show (button);

  button = gtk_button_new_with_label ("Button 2");
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      GTK_SIGNAL_FUNC (callback), (gpointer) "button 2");
  gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
  gtk_widget_show (button);

  gtk_widget_show (box1);
  gtk_widget_show (window);

  gtk_main ();
}

And the same section in C++ mode (using <gtk/cc/gtk.h>)
int main( int  argc,  char *argv[] )
{
  GtkWindow *window;
  GtkButton *button;
  GtkBox *box1;

  gtk_init (&argc, &argv);
  window = GtkWindow::_new (GTK_WINDOW_TOPLEVEL);
  window->set_title_ ("Hello Buttons!");
  window->connect_ ("delete_event", GTK_SIG delete_event, NULL);
  window->set_border_width_ (10);

  box1 = GtkHBox::_new (FALSE, 0);
  window->add_ (box1);

  button = GtkButton::_new_with_label ("Button 1");
  button->connect_ ("clicked", GTK_SIG callback, "button 1");
  box1->pack_start_ (button, TRUE, TRUE, 0)->show_ ();

  button = GtkButton::_new_with_label ("Button 2");
  button->connect_("clicked", GTK_SIG callback, "button 2");
  box1->pack_start_ (button, TRUE, TRUE, 0)->show_ ()

  box1->show_();
  window->show_();
  gtk_main ();

}

Discussion

  • I don't like seperate C++ headers to be maintained. Instead I would love to see this script shipped with the standard GTK+ distributions and run at install time if the target system has C++ and Perl.

  • I don't want to have a seperate C++ library. I don't even like the modern C++ compilers with their pre-main init routines. This wrapper does not even make use of the C++ allocators (new/delete), so all objects can be just fed to any other C routine around.

  • I do like the basic features of C++ like static type checking and the inclusion semantics of single inheritance. There are some patches to the GCC plain C compiler that adds the inheritance syntax. Have a look at substruct-C or even submorph-C. I don't think that any basic object-orientation (like that of GTK+) does need anything more than what the first C++ (version 1.0) had been introducing - and that wasn't multiple inheritance or (horror) name mangling.

  • the names of data members do sometimes clash with the method name, so that the CCheaders does currently generate the methods with an additional underscore attached to the end. This is semi-optimal I'd say. If this script would become a standard GTK+ thingie then the GTK developers would surely care for choosing member/methods names that don't clash in C++ mode.

  • a real wrapper library (like GTK--,) does benefit from the virtual functions of C++ that this skript does not care for. In consequence in a real C++ wrapper you have an easy start in deriving your own widget type. The CCheaders skript does not give you anything on this account.

  • the example presented in here uses a specialty that I have been putting into the CCheaders: if an object-method returns void then the first argument is returned by the generated inline code. That is why show_ () works on button, and not the box.

  • what about detecting the arg types and implicitly adding defaults? All the ints and pointers will have a "= 0" and gboolean will have "= TRUE". Now look again at the example above and count the args you don't need to put in... (I am not in favour of this solutions since it will make it harder to backport the sourcecode to plain C).

Comments

  • send e-mail!!! I do like to get feedback on this idea!!!!
  • (not yet publicly announced)
  • gtk-list@redhat.com: the message has gone out finally.
    • There was a personal e-mail from Keith who likes the idea of mixing C and C++ in one file. He'll try CCheaders later.
    • Havoc Pennington was not too excited about having someone to change the GTK headers and probably favours Sugar.
    • I got into a private conversation with Guillaume Laurent, who did not like the idea of having another C++ thing where there is only one good way for a real C++ programmer - which is to become a GTK-- programmer. Well, this is true actually.

References

GTK--
GTK-- is the most sophisticated C++ wrapper for GTK. If you are a QT programmer (or KDE) you will find everything you like and need in this package. And it tries to be only a thin layer around {GTK+}. You will even find GNOME-- to build on top of GTK/GNOME, and there's GLADE-- as a Visual GTK-- Creator.
wxWindows
WxWindows has an API more or less influenced by Micros~1 MFC. It has the advantage of using the Micros~1 widget dlls under windows to give you the true look and feel of a native Windows application. It's quite a thick layer, but probably the best to write a portable application with native look and feel.
VDK
in contrast to wxwindows, the VDK has its roots in a C++ wrapper for Motif and it aims to provide the best Visual Creator environment.
SDPGTK
the sdpgtk has come its way from a 3D development library, see its homepage at http://www.K-3D.com.
Sugar
unlike the previous 4 wrapper libraries, the "Sugar" header does not need an additional library to be built and then linked with your application. It is just a header file that provides C++ objects that contain a smart pointer to the underlying GTK/C object. It is semi-automatically created from the hand-edited python.defs for GTK.


(C) Mar'00-Apr'00 Guido Draheim CCheaders e-mail:guidod@gmx.de