Now, we will begin to implement some real OO mechanism using GObject library. In this article, we will make our fundamental type Inheritable.

Here’s comes our Base type:

NOTE: PLEASE READ ALL COMMENT CAREFULLY.

In base_instance_init(), we assigned the base_instance_dump() callback. Thus, we can invoke this function by both global function or instance function of BaseClass class. Additional flags G_TYPE_FLAG_DERIVABLE and G_TYPE_FLAG_DEEP_DERIVABLE are also passed to the GTypeFundamentalInfo struct to enable inheritance.

It’s time to define our Derived type:

Our Derived type inherits Base by replacing GTypeClass and GTypeInstance with the corresponding struct of the Base type. According to the memory layout of structs, GTypeClass and GTypeInstance are still the first member of corresponding struct. In derived_get_type(), we register Derived type using g_type_register_static() since it’s not a fundamental at all. And the first parameter is the type id of Base type.

Let’s have some time to look up how to implement polymorphism. In derived_class_init(), we re-assign the base_instance_dump() callback to from the Base‘s implementation to Derived‘s implementation.

Test code:

All source code is available in my skydrive: http://cid-481cbe104492a3af.office.live.com/browse.aspx/share/dev/TestOO. In the TestGObject-{date}.zip/TestGObject4 folder.

We will make fundamental type instantiatable and complete our first usage sample in this article. An object class should be defined firstly:

NOTE: PLEASE READ ALL COMMENT CAREFULLY.

Also, we re-define the class struct:

GTypeClass should be the first member of a class struct, while TypeInstance the first member of a object struct. You may wonder why there’s two int variable in both struct. The foo_class_i is like a static variable in C++ class, while The foo_instance_i is like an instance variable in C++ class. And remember fields in a class struct? It is used as meta info.

The registry function also need modification:

We assigned the instance_init() callback. It is called when a instance of our Foo class is created. You may ask where is the corresponding instance_finalize() callback? Hey, we will discuss it in upcoming articles. The instance_init() callback can be regarded as the constructor of a C++ class. Note, an additional G_TYPE_FLAG_INSTANTIATABLE flag is also added in the GTypeFundamentalInfo struct.

Let’s see how to create an instance:

Congratulations! You’ve finished the learning of our fundamental sample.

All source code is available in my skydrive: http://cid-481cbe104492a3af.office.live.com/browse.aspx/share/dev/TestOO. In the TestGObject-{date}.zip/TestGObject3 folder.

In last article, we defined a fundamental type. But nothing can be done with it. Now, we will extend it to be a classed type, say adding class info into our fundamental type. To do this, we should define a class struct, which can be regard as the meta info of a C++ class:

NOTE: PLEASE READ ALL COMMENT CAREFULLY.

GTypeClass should be the first member of a class struct. You can image the i field to be the version of the class. And we can add a string field to hold the author of this class. There’s also a function pointer bar(). As you may already know, it is used to implement polymorphism, which can be regard as virtual function of a C++ class.

When registering our fundamental type, additional field in GTypeInfo and GTypeFundamentalInfo are filled:

GTypeInfo is the key data structure of GObject type system. It defines how a classed type should be initialized and finalized. Here, we just assigned the class_init() callback. It is called when our FooClass needs initialization. For fundamental and static types, their class_finalize() are never called. We will demo the usage of this callback when introducing dynamic types. Please also note the G_TYPE_FLAG_CLASSED flag passed into GTypeFundamentalInfo struct.

Now, let’s implement our foo_class_init() function. This function is used to initialize fields and assign virtual functions in most time:

Now, we’ve finished our definition of the class struct. Let’s see how to use it:

See? We use g_type_class_ref() and g_type_class_unref() to ref/unref a class, and invoke a function. But its function is still limited. We can just get/set its meta info. It still cannot be instantiated. This will be discussed in the next article.

All source code is available in my skydrive: http://cid-481cbe104492a3af.office.live.com/browse.aspx/share/dev/TestOO. In the TestGObject-{date}.zip/TestGObject2 folder.

These days, I tried to write C code with OO support. I found GObject is such a well-designed library to simplify my implementation. However, the official documents is not so clear sometimes.  It do not provide sufficient information about all its stuff. I had to write my own demo applications to test the usage of some function. Moreover, the source code were also checked for reference.

There are 3 types in GObject type system: Fundamental, static and dynamic. Fundamental types are top-most types. The do not have parent types. They are seldom used, since all fundamental types are pre-defined rather than user-defined.

In this article, I will try to define a fundamental type using in GObject.Here’s the code on how to register a basic fundamental type in GObject, and how it can be used.

NOTE: PLEASE READ ALL COMMENT CAREFULLY.

My fundamental type is created by calling g_type_register_fundamental() function. A GTypeInfo and a GTypeFundamentalInfo struct are passed as parameters. And here comes the linux Makefile. You can use pkg-config to replace my include and lib paths:

NOTE: REPLACE THE WHITESPACE WITH TAB IN MAKEFILES, IF YOU COPY THE CODE DIRECTLY.

The fundamental type is of no use at all presently. In the next article, I will extend my code to add class meta info.

All source code is available in my skydrive: http://cid-481cbe104492a3af.office.live.com/browse.aspx/share/dev/TestOO. In the TestGObject-{date}.zip/TestGObject1 folder.