GOB(1) GOB(1)
GOB 1.0.11
NAME
GOB - The GTK+ Object Builder
SYNOPSIS
gob [ option ] ... file
DESCRIPTION
GTK+ Object Builder is a simple preprocessor for easily creating GTK+
objects. It does not parse any C code and ignores any C errors. It
is in spirit similar to things like lex or yacc.
OPTIONS
-? -h --help
Display a simple help screen.
--version
Display version information (note, --version was not added until
0.92.0)
-w --exit-on-warn
Exit with an error code even when you encounter a warning.
--no-exit-on-warn
Exit with an error only on errors, not on warnings, this is the
default.
--for-cpp
Generate C++ code.
--no-extern-c
Never add the extern "C" to the header.
--no-gnu
Never generate any code with GNU C extensions. However all the
GNU C extensions are always wrapped in #ifdef __GNUC__, so code
using them compiles correctly even on non-GNU compilers. This
option is for purists only. (using GNU extensions some warnings
are eliminated, some ugly hacks and there is better argument type
safety, so it's good to use them)
--no-touch-headers
Don't touch the generated header file unless it really changed,
this avoids spurious rebuilds, but can confuse some make systems
(automake in particular), so it is not enabled by default.
Private header is still touched even if unchanged however.
--always-private-header
Always create a <basename>-private.h file, even if it would be
empty. Otherwise, it is only created when there are private data
members in the class. This option implicitly negates --no-
- 1 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
private-header
--no-private-header
Never create a private header file. If we use any private data
members, define the private data structure at the point in the .c
source where the class definition begins. This option implicitly
negates --always-private-header
-n --no-write
Do not write any output files, just check syntax of the input
file.
--no-lines
Do not print out the '#line' statements into the output. Useful
for debugging the auto-generated generated code.
--no-self-alias
Do not create the Self and SelfClass type aliases and the SELF,
IS_SELF and SELF_CLASS macros.
--no-kill-underscores
Do not remove the initial underscore from method names.
--always-private-struct
Always include the private pointer in the public header file.
This is useful for files which are part of a library and you want
to reserve the right to add some private data members without
breaking binary compatibility.
TYPENAMES
Because we need to parse out different parts of the typename,
sometimes you need to specify the typename with some special syntax.
Types are specified in capitalized form and words are separated by
':'. The first word of the type (which can be empty) is the
"namespace". This fact is for example used for the type checking
macro and the type macro. For "Gtk:New:Button", the macros will be
GTK_IS_NEW_BUTTON and GTK_TYPE_NEW_BUTTON. This colon separated
format of typenames is used in the class declaration header and for
method argument types.
OUTPUT FILES
The filenames are created from the typename. The words are separated
by '-' and all in lower case. For example for an object named
"Gtk:New:Button", the files are gtk-new-button.c and gtk-new-button.h.
If you are using C++ mode, the output .c file will in fact be a .cc
file. If you have any private data members, a private header file
will also be created, called <basename>-private.h (for the example
above it would be gtk-new-button-private.h). The public header file
is created to be human readable and to be used as a reference to the
- 2 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
object. The .c source file is not created as a human readable source
and is littered with #line statements, which make the compiler attempt
to point you to the right line in your .gob file in case of parsing
errors. The output should not be edited by hand, and you should only
edit the .gob file.
INCLUDING NORMAL C CODE IN THE
To include some code directly in the output C file begin with '%{' on
an empty line and end the code with a '%}' on an empty line. These
sections will appear in the output files in the order they are given.
There are several other sections to which you can put code. You can
put it in the 'header' section (which can be abbreviated 'h') and it
will go into the public header file. You can also put it in the
'privateheader' section (abbreviated 'ph') which will make the code go
into the private header file. Sometimes you want some code (other
includes) to appear before the extern "C" and the protecting define.
To do this you can put them into the 'headertop' (or 'ht') section.
You may wish to include code or comments in all the files, which you
can do by putting them into the 'all' (or 'a') section. Similarly,
code you wish to appear at the top of all files go in the 'alltop' (or
'at') section. For example:
%alltop{
/* this will be on top of all output files */
%}
%headertop{
/* this will be on top of the public header */
%}
%privateheader{
/* this will go into the private header file */
%}
%h{
/* will be included in the header */
void somefunc(int i);
%}
%a{
/* will be included in all files */
%}
%{
/* will be included in the C file */
void somefunc(int i)
{
/* some code */
}
%}
- 3 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
INCLUDE FILES
Gob will automatically include the class header file at the top of the
.c source file. If you wish to include it somewhere else, put the
include into some %{ %} section above the class definition, and gob
will not include it automatically. This way you can avoid circular
includes and control where in the file do you want to include the
header.
If you made any data members private, gob will also create a source
file that will be called <basename>-private.h. Same rule as above
applies for this just as it does for the regular header file. If you
do explicitly include the regular header file, you should always
include this private header file below it. That is, if you use any
private data members. If you don't, the private header file
automatically includes the public header file, and thus the public
header file will be indirectly included at the very top of the file.
MAKING A NEW CLASS
The class header:
There can be only one class per input file. Defining a class is sort
of like in Java, you define the class and write inline code directly
into the class definition. To define a class you need to specify the
new object name and the name of the object from which it is derived
from, such as this "class <new type> from <parent type> { <class code>
}". For example:
class Gtk:New:Button from Gtk:Button {
<class code>
}
Data members:
There are five types of data members. Three of them are normal data
numbers, one is class wide (global) in scope and one is a virtual one,
usually linked to a normal data member or a class wide data member.
The three normal data members are public, protected and private.
Public and protected are basically just entries in the object
structure, while private has it's own dynamically allocated private
structure. Protected members are always put after the public one in
the structure and are marked protected in the header file. There is
only one identifier allowed per typename unlike in normal C. Example:
public int i;
private GtkWidget *h;
protected long k;
- 4 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
Public and protected data members are accessed normally as members of
the object struct. Example where 'i' is as above a public data
member:
object->i = 1;
The private data members are defined in a structure which is only
available inside the .c file, or by including a private header file.
You must access them using the structure _priv. Example where 'h' is
the private data member (as in the above example):
object->_priv->h = NULL;
The _priv structure is defined in the <basename>-private.h. This file
is automatically included if you don't include it yourself. You
should always explicitly include it in your .gob file if you
explicitly also include the main header file. The reason it is a
separate header file is that you can also include it in other places
that need to access this objects private data, such as if you have the
majority of functionality of an object in a separate .c file. Or if a
derived object needs to access the protected methods.
In case you use the --no-private-header option, no private header file
is created and you can only access the _priv pointer below the class
definition in the .gob file.
Also note that this structure is dynamically allocated, and is freed
in the finalize handler. If you override the finalized handler, your
code will be run first and only then will the _priv structure be
freed.
Classwide data members:
Sometimes you want a datamember to be shared by all objects. You then
need the "classwide" scope keyword. So for example the following adds
a global member foo:
classwide int foo;
To access the member you do the standard voodoo of getting the class
from the object and casting it to your class pointer. Thus the
following would work:
SELF_CLASS(GTK_OBJECT(object)->klass)->foo = 20;
Automatic Initialization (0.93.0 and higher only):
You can automatically initialize the public private and protected data
members without having to add an init method. The advantage here is
- 5 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
that initialization is kept close to the definition of the data member
and thus it's easier to check. To do this, just add a '=' followed by
a number or a token. It is also possible to include arbitrary C code
for more elaborate initializations by putting it all in curly braces.
Note that the curly braces will not be printed into the output, but
since gob does not C parsing it needs them to figure out where the C
code ends. The code will be inserted into the init method, above the
user defined body. So for example the following will initialize an
integer to -1 and a string with a newly allocated string of "hello".
public int foo = -1;
private char *bar = {g_strdup("hello")};
Automatic Destruction (0.93.0 and higher only):
Most data stored as pointers needs to have a function called when the
object is destroyed, to either free it or give up a reference. Gob
will let you define a function to be called on the data the object is
destroyed. This is achieved by putting 'destroywith' followed by a
function name after the variable definition. It is only called if the
data you defined this on is not NULL, so you cans specify functions
which do not handle NULL. It is very much like the GDestroyNotify
function used in GTK+ and glib in many places. Unlike many other
places, gob will not enforce any kind of type safety here so be a
little bit more careful. Any function you give it will be called as a
"void function(void *)". It will in fact be cast into such a form
before called. This is to avoid spurious warnings for gtk calls to
subclass methods. The function needs not be of that form exactly, it
just has to take one argument which is the pointer to the data. You
should also not define this on any non-pointer data as the results may
be undefined. Example:
public Gtk:Widget *window = NULL
destroywith gtk_widget_destroy;
public char *foo = {g_strdup("bar")}
destroywith g_free;
Note that the function name you give must be a real function and not
macro. Also note that this is always called in the "destroy" method
of GtkObject. It is always called after any user defined body of the
destroy handler.
Sometimes you may want to run arbitrary code on destruction. While
this can be perfectly well done in the destroy handler. Depending on
the style you may want to include all destruction/initialization code
together with the definition of the data member. Thus you may want to
put arbitrary code which will then be inserted into the "destroy"
method of GtkObject. This can be done with the "destroy" keyword
followed by arbitrary code in curly braces. Inside this code a macro
called VAR will be define which refers to your variable. So for
- 6 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
example destroying a GString can be either done with a helper routine
or the following code:
public GString *string = {g_string_new(NULL)}
destroy {
if(VAR) g_string_free(VAR, TRUE);
};
The thing to remember with these is that there are many ways to do
this and you'd better be consistent in your code in how you use the
above things. Also defining a helper routine that will do the
destruction will be a nicer thing to do if that's a possibility. The
"destroy" keyword with code does take up more space in the file and it
may become more cluttered.
The data is zeroed out after being destroyed. This is to make
debugging easier in case your code might try to access an already
destroyed object. In case you have overridden the destroy method,
your code will be run first and only then will the destructors be
called. You should not however make any assumptions about the order
at which the destructors are called. If you have interdependencies
between destructors for different data members, you will have to do
this in your own destroy override function.
GTK+ Arguments:
The fourth type of a data member an argument type. It is a named data
member which is one of the features of the GTK+ object system. You
need to define a get and a set handler. They are fragments of C code
that will be used to get the value or set the value of the argument.
Inside them you can use the define ARG to which you assign the data or
get the data. You can also use the identifier "self" as pointer to
the object instance. The type is defined as one of the gtk type
enums, but without the GTK_TYPE_ prefix. For example:
public int height;
argument INT height set { self->height = ARG; } get { ARG = self->height; };
If you don't define a set or a get handler it will be a read-only or a
write-only argument. If you want to add extra argument flags, add
them into parenthesis after the argument keyword, separated by '|' and
without the GTK_ARG_ prefix. For example:
public int height;
argument (CONSTRUCT) INT height get { ARG = self->height; };
This makes the argument settable even before the object is
constructed, so that people can pass it to gtk_object_new function.
Useful is also CONSTRUCT_ONLY flag which makes the argument only
available during construction of the object.
- 7 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
Since 0.92.1, gob creates macros which can be used for type safe
access to gtk arguments. The macros are called <type>_ARG_<argument
name>(x) and <type>_GET_ARG_<argument name>(x). They define both the
string and the value part of the argument. So for setting an argument
of height, one would use (for object type My:Object):
gtk_object_set (GTK_OBJECT (object),
MY_OBJECT_ARG_HEIGHT (7),
NULL);
And for getting, you would use:
int height;
gtk_object_get (GTK_OBJECT (object),
MY_OBJECT_GET_ARG_HEIGHT (&height),
NULL);
Note however that the type safety only works completely on GNU C
compilers. The code will compile on other compilers but with minimal
type safety.
To get good type safety on POINTER types however, you should specify
an optional C type that gob should use. For other then POINTER types
this is redundant but possible. To do this, place '(type <c type>)'
right after the GTK+ type. Example:
argument POINTER (type char *) foo set { /* foo */ } get { /* bar */ };
Sometimes it can become tiresome to type in the set and get handlers
if they are trivial. So gob since version 0.93.0 provides automatic
argument linking to data members. There are three different cases it
handles, direct link (keyword 'link'), string linking (keyword
'stringlink') and object linking (keyword 'objectlink'). You just
place the keyword after the argument name instead of the get/set
handlers. It will link to a data member of the same name that was
defined earlier in the input file. Best is to see examples:
public int foo;
argument INT foo link;
is just like
public int foo;
argument INT (type int) foo
get { ARG = self->foo; }
set { self->foo = ARG; };
Similarly,
private char * foo;
- 8 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
argument POINTER foo stringlink;
is just like
private char * foo;
argument POINTER (type char *) foo
get {
ARG = g_strdup(self->_priv->foo);
} set {
g_free(self->_priv->foo);
self->_priv->foo = g_strdup(ARG);
}
And for the objectlink we would have:
public Gtk:Object * foo;
argument POINTER foo objectlink;
is just like
protected Gtk:Object * foo;
argument POINTER (type Gtk:Object *) foo
get {
ARG = self->foo;
} set {
if(ARG != NULL)
gtk_object_ref(ARG);
if(self->foo != NULL)
gtk_object_unref(self->foo);
self->foo = ARG;
}
As you see it will handle NULLs correctly (for the string, g_free and
g_strdup handle NULLs). And it will also handle private, protected
and public members. For objectlink, just a pointer is returned on
get, if you wish to keep it around, you should call gtk_object_ref on
it. For stringlink, get makes a copy of the string which you should
free after use. This is the behaviour since 1.0.2.
You can also automatically export get and set methods for each of the
arguments by appending '(export)' flag before the get and set
statements. For example:
public int foo;
argument INT (type int) foo (export)
get { ARG = self->foo; }
set { self->foo = ARG; };
Will export public methods get_foo(self) and set_foo(self, int foo)
for you automatically. Note that this behaviour is new in 1.0.10.
- 9 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
Methods:
There is a whole array of possible methods. The three normal,
"familiar" method types are private, protected and public. Public are
defined as normal functions with a prototype in the header file.
Protected methods are defined as normal methods (which you can call
from other files), but their prototype is placed in the private header
file. Private methods are defined as static functions with prototypes
at the top of the .c file. Then there are signal, virtual and
override methods. More on those later. You can also define init and
class_init methods with a special definition if you want to add code
to the constructors or you can just leave them out. You can also not
define a body for a method, by just using ';' instead of a body. This
will define an empty function. You can't do this for non-void regular
public, private or protected methods, however it is acceptable for
non-void virtual, signal and override methods.
Function argument lists:
For all but the init and class_init methods, you use the following
syntax for arguments. The first argument can be just "self", which
gob will translate into a pointer to the object instance. The rest of
the arguments are very similar to normal C arguments. If the typename
is an object pointer you should use the syntax defined above with the
words separated by ':'
<type> <argument id>
or
<type> <argument id> (check <list of checks>)
The checks are glib type preconditions, and can be the following:
"null", which tests pointers for being NULL, "type" which checks GTK+
object pointers for being the right type, "<test> <number>" which
tests numeric arguments for being a certain value. The test can be a
<,>,<=,>= != or ==. Example:
public int foo(self, int h (check > 0 < 11), Gtk:Widget *w (check null type))
This will be the prototype of a function which has a self pointer as
the first argument, an integer argument which will be checked and has
to be more then 0 and less then 11, and a pointer to a GtkWidget
object instance and it is checked for being null and the type will
also be checked.
Error return:
Methods which have a return value, there also has to be something
returned if there is an error, such as if a precondition is not met.
The default is 0, casted to the type of the method. If you need to
return something else then you can specify an "onerror" keyword after
the prototype and after that a number, a token (an identifier) or a
- 10 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
bit of C code enclosed in braces {}. The braces will not be printed
into the output, they just delimit the string. For example:
public void * get_something(self, int i (check >= 0)) onerror NULL {
...
}
The onerror value is also used in overrides that have a return value,
in case there isn't a parent method, PARENT_HANDLER will return it.
More about this later.
Default return:
Some signal and virtual methods have a return type. But what happens
if there is no default handler and no one connects to a signal. GOB
will normally have the wrappers return whatever you specify with
onerror or '0' if you haven't specified anything. But since 0.93.2
you can specify a default return value with the keyword 'defreturn'.
It's use is identical to the use of onerror, and you can in fact use
both at the same time. Example
virtual int get_some_int(self) onerror -1 defreturn 10 ;
That is an empty virtual method (in C++ terms a pure virtual). If you
never specify any handler for it in the derived children it will just
return 10.
Constructor methods:
There are two methods that handle the construction of an object, init
and class_init. You define them by just using the init or class_init
keyword with an untyped argument in the argument list. The argument
will be usable in your function as a pointer to your object or class
depending if it's init or class_init. For example:
init(self) {
/* initialize the object here */
self->a = 9;
self->b = 9;
}
class_init(class) {
/* initialize the class, this is rarely needed */
class->blah = NULL;
}
The class_init function is very rarely needed as all standard class
initialization is taken care of for you by gob itself. The init
function should on the other hand be used whenever you need to
construct or initialize anything in the object to put it into a sane
state. Sometimes you need some arguments, for this you should either
- 11 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
use a construct method and a new function like many GTK+ widgets,
and/or a CONSTRUCT or CONSTRUCT_ONLY type of an argument.
Virtual methods:
Virtual methods are basically pointers in the class structure, so that
one can override the method in derived methods. They can be empty (if
you put ';' instead of the C code). A wrapper will also be defined
which makes calling the methods he same as public methods. This type
of method is just a little bit "slower" then normal functions, but not
as slow as signals. You define them by using "virtual" keyword before
the prototype. If you put the keyword "private" right after the
"virtual" keyword, the wrapper will not be a public method, but a
private one. You can do the same with "protected" to make a protected
wrapper.
Signals:
Signals are methods to which the user can bind other handlers and
override the default handler. The default handler is basically the
method body. This is the most versatile and flexible type of a method
and also the slowest. You need to specify a whole bunch of things
when you define a signal. One thing is when the default handler will
be run, first or last. You specify that by "first" or "last" right
after the "signal" keyword. Then you need to define the gtk enum
types (again without the GTK_TYPE_ prefix). For that you define the
return types and the types of arguments after the "self" pointer (not
including the "self" pointer). You put it in the following syntax
"<return type> (<list of arguments>)". If the return type is void,
the type should be "NONE", the same should be for the argument list.
The rest of the prototype is the same as for other method types. The
body can also be empty, and also there is a public method wrapper
which you can use for calling the signal just like a public method.
Example:
signal first INT(POINTER,INT)
int do_something(self, Gtk:Widget *w (check null type), int length)
{
...
}
or
signal last NONE(NONE) void foo(self);
If you don't want the wrapper that emits the signal to be public, you
can include the keyword "private" after the "signal" keyword. This
will make the wrapper a normal private method. You can also make a
protected wrapper by using "protected" instead of "private".
- 12 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
If you don't define a "first" or a "last", the default will be taken
as "last".
You can also add additional flags. You do this just like with the
argument flags, although this is probably very rare. These are the
GTK_RUN_* flags, and you can add them without the GTK_RUN_ prefix into
a parenthesis, just after the "signal" keyword. By default all public
signals are GTK_RUN_ACTION.
Since 1.0.6, gob creates wrapper signal macros for signal connection
typesafety, at least on gnu compilers. These macros are named
<type>_SIGNAL_<signal name>(func), where func is the function pointer.
This pointer must be of the correct type, or you will get an
initialization from wrong pointer type warning. This macro, much like
the argument macros, wraps both the name and the function pointer
parameters. For example to connect a signal "changed" to a function
"foo", you would do:
gtk_signal_connect (GTK_OBJECT (object),
MY_OBJECT_SIGNAL_CHANGED (foo),
NULL);
Override methods:
If you need to override some method (a signal or a virtual method of
some class in the parent tree of the new object), you can define and
override method. After the "override" keyword, you should put the
typename of the class you are overriding a method from. Other then
that it is the same as for other methods. The "self" pointer in this
case should be the type of the method you are overriding so that you
don't get warnings during compilation. Also to call the method of the
parent class, you can use the PARENT_HANDLER macro with your
arguments. Example:
override (Gtk:Container) void
add (Gtk:Container *self (check null type), Gtk:Widget *wid (check null type))
{
/* some code here */
PARENT_HANDLER(self, wid);
}
If the function has a return value, then PARENT_HANDLER is an
expression that you can use. It will return whatever the parent
handler returned, or the "onerror" expression if there was no parent
handler.
Method names:
Inside the code, aliases are set for the methods, so that you don't
have to type the class name before each call, just the name of the
- 13 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
method. Example:
private int
foo(self)
{
return self->len;
}
private int
bar(self,int i)
{
return foo(self) + i;
}
Underscore removal (0.93.5+):
Sometimes this causes conflicts with other libraries. For example a
library might have already used the identifier foo. You can prepend
an underscore to the name in the .gob file. This will make the local
short alias have an initial underscore, but it will not change the
name of the actual name of the function. For example:
class My:Object from Gtk:Object {
public void
_foo(self) {
/* foo body */
}
public void
bar(self) {
/* short calling convention */
_foo(self);
/* long calling convention */
my_object_foo(self);
}
}
Thus you see that the "_foo" method still generates the method
"my_object_foo" just as "foo" would generate. You can turn off this
behavior if you depend on the old (pre 0.93.5) behavior with the --
no-kill-underscores option. This also means that if both "_foo" and
"foo" are defined, it is treated as a conflict.
This does not apply to override methods. Override methods are special
beasts and this is not necessary and would make the code behave in
weird ways.
Making new objects:
You should define a new method which should be a normal public method.
Inside this method, you can use the GET_NEW macro that is defined for
you and that will fetch a new object, so a fairly standard new method
would look like:
- 14 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
public GtkObject *
new(void) {
GtkObject *ret = GET_NEW;
return GTK_OBJECT (ret);
}
You should not a subtle peculiarity of the GTK+ object system here.
If there is any code inside the GTK_OBJECT macro argument, it will get
executed multiple times. This means that things such as
GTK_OBJECT(GET_NEW) would actually create 4 objects, leaking 3 of
them. A good rule is to be careful with all macros.
Self alias casts:
There are some standard casts defined for you. Instead of using the
full macros inside the .c file, you can use SELF, IS_SELF and
SELF_CLASS. Using these makes it easier to for example change class
names around.
Self alias types:
Since 0.93.5, there have also been defined the Self and SelfClass
types inside your .c file. These serve the same function as the
above, they make it easier to type and easier to change typenames
around which can help a lot during prototyping stage. However you
should note that the Self type should not be used in function
prototypes as one of the arguments or as a return value type. This is
because this is a simple C typedef which is only available inside you
aliases by passing --no-self-alias to
DEALING WITH DIFFERENT GOB VERSIONS
Defines:
In your generated C file, you can use the defines GOB_VERSION_MAJOR
GOB_VERSION_MINOR and GOB_VERSION_PATCHLEVEL if you wish to for
example use a feature that is only available in some newer gob
version. Note however that you can only use these defines in the C
code portions of your .gob file, and #ifdef's cannot span multiple
functions. Check the BUGS section for more on using the C
preprocessor and gob. Also note that these have only been available
since the 0.92.1 version of gob.
Minimum version requires:
You can also make your .gob file require at least certain version of
gob. You do this by putting 'requires x.y.z' (where x.y.z is the
version number) outside of any C block, comment or class, usually you
should make this the first line in the file or close to the top. If
gob finds this and the version of gob used to compile the code is
- 15 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
lower then that listed in the require, gob will generate an error and
exit. For example to require that gob version 0.92.1 or higher be
used to compile a file, put this at the top of that file:
requires 0.92.1
It should be noted however that this feature was not added until
0.92.1, and so if the file gets compiled by a lower version, gob would
generate a syntax error. Thus by putting in a requires line, you are
implicitly requiring at least 0.92.1.
C++ MODE
There is a C++ mode so that gob creates C++ compiler friendly files.
You need to use the --for-cpp argument to gob. This will make the
generated file have a .cc instead of a .c extension, and several
things will be adjusted to make it all work for a C++ compiler. One
thing that will be missing is an alias to the new method, as that
clashes with C++, so instead you'll have to use the full name of the
method inside your code. Also note that gob does not use any C++
features, this option will just make the generated code compile with a
C++ compiler.
OVERRIDING THE GET_TYPE METHOD
The get_type is not really a method, but a function which initializes
your object. Recently objects appeared which require you to make a
custom get_type function (BonoboXObject currently, see next section
for direct BonoboXObject support). So in 1.0.7 it is now possible to
override this function. To do so, just define a new public method
called get_type, with no arguments. Example:
public GtkType
get_type (void)
{
/* code goes here */
return some_type;
}
DIRECT BonoboXObject SUPPORT
If you want to build a BonoboXObject class gob has direct support for
these classes since 1.0.9. Just create a new object that derives from
Bonobo:X:Object. Then use a "BonoboX" class flag with the interface
name as an argument. The interface name should be as you would type
it in C, that is with underscores as namespace separators. Then you
add the methods (using exact same names as in the idl file) and
prepend those methods with a BonoboX keyword. For example imagine you
have an interface GNOME/Foo/SomeInterface, with a method fooBar that
takes a single string:
- 16 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
class Foo:Some:Interface from Bonobo:X:Object
(BonoboX GNOME_Foo_SomeInterface) {
BonoboX
private void
fooBar (PortableServer_Servant servant,
const CORBA_char *string,
CORBA_Environment *ev)
{
Self *self = SELF (bonobo_object_from_servant (servant));
/* your code here */
}
/* rest of class */
}
Note that the implementation method can be private, in fact that's
probably a good idea to do. It won't work to make this a signal, it
can however be a virtual. Note that the method prototype must match
the one from the interface header file, or you will get a bad
assignment warning. You should check the header file generated by
orbit-idl and see the epv structure for the correct prototypes if you
can't figure them out from the idl itself. Also note that the first
argument is not "self", but the servant and you must use
bonobo_object_from_servant function to get the actual object pointer.
IDENTIFIER CONFLICTS
Gob will need to define some local variables and functions in the
generated files, so you need to take some precaution not to conflict
with these. The general rule of thumb is that all of these start with
three underscores. There is one, "parent_class" which doesn't because
it's intended for use in your code. For virtuals or signals, you
cannot use the identifier __parent__ which is used for the parent of
the object. You should actually never access __parent__ either as it
not guaranteed that it will stay named this way. Data members cannot
be named __parent__ nor _priv. For methods, you cannot use the
identifiers "init" or "class_init" unless you mean the constructor
methods. You shouldn't generally use 3 underscores even in override
method argument lists and virtual and signal method names as it might
confuse the PARENT_HANDLER macro. In fact avoiding all names with
three underscores is the best policy when working with gob.
Also note that starting with version 0.93.5, method names that start
with a an underscore are equivalent to the names without the initial
underscore. This is done to avoid conflicts with the aliases. Thus
you can define the method as "_name", if "name" happens to be some
standard library function. This is the same as defining it as "name"
except that the local alias will be "_name" rather then "name".
- 17 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
There are a couple of defines which you shouldn't be redefining in the
code or other headers. These are SELF, IS_SELF, SELF_CLASS, ARG, VAR,
PARENT_HANDLER, GET_NEW, GOB_VERSION_MAJOR, GOB_VERSION_MINOR and
GOB_VERSION_PATCHLEVEL.
As for types, there are Self and SelfClass types which are only
defined in your source files. Their generation (just like the
generation of the SELF macros) can be turned off, see command line
options.
USING GTK-DOC STYLE INLINE DOCUMENTATION
If you want to use gtk-doc style inline documentation for your
objects, you can do one of two things. First, you could include the
inline documentation comments in your %{ %} section which will then be
put verbatim into the output source file. This is the way you should
use for functions you define outside of the class.
For class methods, you should use a gtk+ style comment, however it can
be indented any number of tabs or spaces and you can use the short
method name without the type prefix. Gob will automatically try to
extract these and translate to full names and put them in the output
source file. An example would be:
class Gtk:Button:Example from Gtk:Button {
/**
* new:
*
* Makes a new #GtkButtonExample widget
*
* Returns: a new widget
**/
public
GtkWidget *
new(void)
{
return GTK_WIDGET(GET_NEW);
}
}
If the function you are documenting is a signal or a virtual then it
will be documenting the wrapper that starts that virtual function or
emits that signal.
DEALING WITH CIRCULAR HEADERS
Sometimes you may need to use an object of type MyObjectA in the
MyObjectB class and vice versa. Obviously you can't include headers
for both. So you need to just declare the typedef in the header of A
for B, and the other way around as well. The headers generated since
v0.92.2 include a protecting define before it declares the typedef.
- 18 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
This define is the __TYPEDEF_<upper case object name>__. So inside
my-object-a.h there will be this:
#ifndef __TYPEDEF_MY_OBJECT_A__
#define __TYPEDEF_MY_OBJECT_A__
typedef struct _MyObjectA MyObjectA;
#endif
Now instead of including my-object-a.h in the header section of my-
object-b.gob, just copy the above code there and you're set for using
MyObjectA as a type in the method parameters and public types.
Another way to get out of this problem is if you can use those types
only in the private members, in which case they won't be in the
generated public header.
BUILDING WITH MAKE
If you are using normal makefiles, what you need to do is to add a
generic rule for .gob files. So you would include the following in
the Makefile and then just use the .c and .h files as usual (make sure
the space before the 'gob' is a tab, not spaces):
%.c %.h %-private.h: %.gob
gob $<
BUILDING WITH AUTOCONF and AUTOMAKE
This is a little bit more involved. Basically the first thing to do
is to check for GOB in your configure.in file. You can use the
supplied m4 macro which will also check the version of gob. Basically
you include this:
GOB_CHECK(0.93.4)
This will replace @GOB@ in your makefiles with the full path of gob.
Thus when adding the generic rule to your Makefile.am file, it should
look like:
%.c %.h %-private.h: %.gob
@GOB@ $<
For Makefile.am you have to set up a couple more things. First you
have to include the generated .c and .h files into BUILT_SOURCES
variable. You have to include both the .gob and the .c and .h files
in the SOURCES for your program.
- 19 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
DEBUGGING
GOB does several things to make debugging the code easier. First it
adds preprocessor commands into the output c file that point to the
correct places in your .gob input file. However sometimes there might
be some bigger confusion and this is just not helpful. In this case
you will probably want to have gcc point you directly at the generated
files. For this use the --no-lines command line option. You should
also note that these commands are not generated for the public header
file at all. If there is an error which points you to the public
header file, make sure you fix this error in the .gob file, otherwise
your changes will not have any effect after gob recompiles the sources
again.
Sometimes you might want to know which method you are in for some
debugging output. GOB will define __GOB_FUNCTION__ macro, which is
just a string constant with a pretty name of the method.
BUGS
The lexer does not actually parse the C code, so I'm sure that some
corner cases or maybe even some not so corner cases of C syntax might
confuse gob completely. If you find any, send me the source that
makes it go gaga and I'll try to make the lexer try to handle it
properly, but no promises.
Another thing is that gob ignores preprocessor macros. Since gob
counts braces, the following code won't work:
#ifdef SOME_DEFINE
if(foo) {
#else
if(bar) {
#endif
blah();
}
To make this work, you'd have to do this:
#ifdef SOME_DEFINE
if(foo)
#else
if(bar)
#endif
{
blah();
}
There is no real good way we can handle this without parsing C code,
so we probably never will. In the future, I might add #if 0 as a
comment but that's about as far as I can really take it and even that
is problematic. Basically, if you use gob, just don't use the C
- 20 - Formatted: December 18, 2025
GOB(1) GOB(1)
GOB 1.0.11
preprocessor too extensively.
Comments will not get through to the generated files unless inside C
code. This is not the case for gtk-doc style comments which are
supported.
The short name aliases are actually implemented as pointers to
functions. Thus if you want to get the pointer of a function using
the short name alias you can't use the '&'. Thus:
void (*foo)(Self *);
/* this will NOT work */
foo = &short_name;
/* this will work */
foo = short_name;
/* Both of these will work */
foo = &my_class_long_name;
foo = my_class_long_name;
AUTHOR
George Lebl <jirka@5z.com>
- 21 - Formatted: December 18, 2025