Generally, BIOS info can be found by dmidecode utility(run as root), like:

Here, I retrieve it by using libhd library provided in hwinfo utility:

In previous articles, I was not able to use Qt’s debug package provided by Ubuntu. Now, I will explain how to use them.

Our simple application:

Our *.pro file, you should enable the debug build:

1. Build your debug version of application:

2. Install Qt’s debug package:

3. Install the Qt source:

Now you can start debugging your application. Since Qt’s debug symbols are installed in /usr/lib, It does not follow the GDB’s global debug directory described here. We should tell GDB to load these symbols manually:

We set a breakpoint at the beginning of main function to load all shared libraries. Next, we will load symbols for libQtCore.so.4. The symbol will be loaded in the start address of it (0xb7652510):

Now, you are able to step into the Qt library, but no source is attached:

Source files are attached by:

See the source and backtrace? 🙂

From the last series of GObject library, we know the approach of OOP using C. Now, I just want to have a comparison of OO implementation in all leading programming languages: C, C++, Java and C#. I will use C++/Qt in this article. Apart from basic features like encapsulation, inheritance, polymorphism, I will demonstrate how to use advanced features including properties, meta info and event-driven programming.

Now, let’s start. Since C++ supports inheritance and polymorphism in language level. They are not the problem. When encounter encapsulation, it does not do well. We CAN declare member variables as private to prohibit their directly access. But the internal implementation is still exposed. When adding/removing private member variables, the class structure is changed. This can cause binary compatible issues. According to the guide of Qt, we define a private class to hold all private member variables, and add the pointer of it to our public class. The size of pointer is constant in all platforms, so this will not break the binary compatibility. Here’s the code:

NOTE: To use Qt’s object mechanism, your class should inherit QObject class and include the Q_OBJECT macro.

Just note the forward declaration of QBasePrivate private class. It is define in *.c file, and cannot be used by client applications. We defined a d_ptr protected member variable of this type to hold all private data values. Qt library provideds a series of easy-to-use macros to support this scheme to implementation:

Qt library supports properties and meta info. properties are defined with Q_PROPERTYmacro, while class meta info are defined with Q_CLASSINFO. Both of them can be inherited by derived classes. Last is Qt’s event-driven mechanism: signals/slots. Since they are also based on QObject, we had to define a test class to include all slots:

Test code:

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

Recall there are 3 types in GObject type system: Fundamental, static and dynamic. A fundamental type is a top-most type which has no parent type. Most of them are pre-defined. Static types never load/unload its class type (say, their class struct) at runtime, since they are static. On the contrary, dynamic types can be dynamically loaded/unloaded at runtime. They are normally used within a module.

We can call g_type_register_dynamic() to register a dynamic type. When used in a module of GObject library (may be a GTypeModule type), We can also call g_type_module_register_type() to create your dynamic types. g_type_register_dynamic() is invoked for you in that function. Let’s go through the code:

NOTE: PLEASE READ ALL COMMENT CAREFULLY.

The implementation structure may be a little different with the stuff when creating a static type. An additional parameter GTypeModule is passed in. It represents the module your dynamic type belongs to. So, when the module is unloaded, all dynamic types in it are unaccessible.

Also note the bar_type_class_finalize() function. We use it to override the finalize() virtual function in GObjectClass. Now you can do un-initialiation in this function. It is like the destructor in a C++ class.

Let’s move on to the module type. This type inherits GTypeModule:

GTypeModule is an abstract type. We should implements its load() and unload() virtual function.

Our test code:

Another dynamic type BarType is defined in addition to FooType to demo the usage. The output maybe:

See the init/finalize process?

At the end of my note, Let me summarize to compare GObject library with C++ implementation:

1. Member Variables:

GObject C++
in class struct class meta info
in object struct class instance member
global variable class static member

2. Function Callbacks:

GObject C++
base_init init class dynamic meta info
base_finalize finalize dynamic class meta info, only dynamic types use it
class_init init class static meta info
class_finalize finalize class static meta info, only dynamic types use it
instance_init init instace, like C++ constructor
override finalize in GObjectClass finalize instance, like C++ destructor

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

Interfaces usage in library is like class usage. We need to define a interface struct, but no object struct is needed:

NOTE: PLEASE READ ALL COMMENT CAREFULLY.

Then we register the interface using g_type_register_static() with G_TYPE_INTERFACE as first parameter. For interfaces, we only need to assign base_init() and base_finalize()callbacks.

As described in the official document, we should allocate dynamic memebers of class struct in base_init(). Otherwise, all copies of the class struct share only one copy of dynamic members. This leads to problems.

Let’s define the type which implements the interface:

Note the naming convention I used here. Our FakeDesktop class will implement the FakeIServer interface and another FakeIClient interface. This time do not use corresponding interface struct as the first members of FakeDesktop and FakeDesktopClass. Interface info will be added dynamically when initialize a real instance of FakeDesktop. Let’s move to the *.c code:

Note the g_type_add_interface_static() function call to add interface info. The interface info is defined in a GInterfaceInfo struct. We just make use of the interface_init() callback. In it, we assign function pointers of corresponding interface to our implementation function. We can add multiple interface infos to implement them.

Finally, the test code:

In runtime, if your classed type implements an interface, it will be considered as the interface type (is-a).

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