http://www.ibm.com/developerworks/cn/linux/l-gobject/
簡單的說,GObject對象系統是一個建立在GLIB基礎上的,用C語言完成的,具有跨平台特色的、靈活的、可擴展的、非常容易映射到其它語言的面向對象的框架。如果你是一個C語言的執着的追隨者,你沒有理由不研究一下它。
快速上手Gobject
http://blog.csdn.net/acs713/article/details/7778051
What is G-object?
Why Bother to use Gobject?
1 )使用面向對象的設計方法來編程。 GObject 僅依賴於 GLib 和 libc , 通過它可使用純 C 語言設計一整套面向對象的軟件模塊。
2 )多語言交互。在為已經使用 GObject 框架寫好的函數庫建立多語言連結時,可以很容易對應到許多語言,包括 C++ 、 Java 、 Ruby 、 Python 和 .NET/Mono 等。 GObject 被設計為可以直接使用在 C 程序中,也 封裝 至其他語言。
32位的整型,並調用了function_foo函數。就
如你看到的,C函數的調用由gcc實現成了本地機器碼的調用(這是實現起來最快的方法)。有了gcc這個第三方,我們的代碼與
機器的溝通更順暢了!記住:GType/GObject庫不僅僅是為了設計向C開發者提供面向對象的特性,也是為了透明的跨語言互通性。
做一個受歡迎的協調者
(1)找到函數所處的位置:這個意味着在C編譯器編譯成的二進制文件中尋找這個函數。
(2)在可執行的內存中,載入有關這個函數的相關代碼。
(3)在調用這個函數前,將Python的參數轉換為C兼容的參數。
(4)用正確的方式調用這個函數。
(5)將C函數的返回值轉換成Python兼容的變量並將其返回至Python代碼中。

來自動轉換函數參數和進行函數調用在不同的運行環境之間。
GOBJECT模擬封裝
在 GObject世界里,類是兩個結構體的組合,一個是實例結構體,另一個是類結構體。有點繞。類、對象、實例有什么區別?可以這么理解,類-對象-實例,無非就是類型,該類型所聲明的變量,變量所存儲的內容。后面可以知道,類結構體初始化函數一般被調用一次,而實例結構體的初始化函數的調用次數等於對象實例化的次數。所有實例共享的數據,可保存在類結構體中,而所有對象私有的數據,則保存在實例結構體中。

GOBJCT如何模擬私有屬性
C語言實現CLASS域GOBJECT支持
如何實現gobject面向對象支持呢?
很簡單,我們只需要建立自己的頭文件,並添加一些宏定義G_DEFINE_TYPE即可。

這樣,GUPnPContext就成為了Gobject庫認可的一類合法公民了,即成功的把GUpnPContextClass類所代表的type(類型)注冊到了glib類型系統中,並且將成功獲取到一個類型ID。
也就是說,當你設計新類時,GUPnPContext可以被考慮加進你的繼承體系,同時GUPnPContext也可以被用於組合成其他的類。
進一步理解GType類型系統
GOBEJCT如何實現繼承
GOBJECT構造函數
多態的概念
為什么要在GOBJECT引入多態?
(1)Gobject為每個子類在內存中保存了一份包含成員函數指針的表. 這個表,就是我們在C++經常說到的虛方法表(vtable)。當你想調用一個虛方法時,你必須先向系統請求查找這個對象所對應的虛方法表。這張表包含了一個由函數指針組成的結構體。在調用這些函數時,需要在運行時查找合適的函數指針,這樣就能允許子類覆蓋這個方法,我們稱之為“虛函數”。
(2) Gobject系統要求我們向它注冊新聲明的類型,系統同時要求我們去向它注冊(對象的和類的)結構體構造和析構函數(以及其他的重要信息),這樣系統就能正確的實例化我們的對象。
(3)Gobject系統通過枚舉化所有的向它注冊的類型來記錄新的對象類型,並且要求所有實例化對象的第一個成員是一個指向它自己類的虛函數表的指針,每個虛函數表的第一個成員是它在系統中保存的枚舉類型的數字表示。
由常用的 g_object_new () 想到的
(1)實現xx_xx_set_property與xx_xx_get_property函數,完成g_object_new函數“屬性名-屬性值”結構向Gobject子類屬性的映射;
(2)在Gobject子類的類結構體初始化函數中,讓Gobject基類的兩個函數指針set_property與get_property分別指向xx_xx_set_property與xx_xx_get_property。
(3)在Gobject子類的類結構體初始化函數中,為Gobject子類安裝具體對象的私有屬性。
可以看出,set_property是Gobject的虛函數實現,是運行時的多態。
GOBJECT 多態: 將優雅展示於外界假設我們需要一種數據類型,可以實現一個可以容納多類型元素的鏈表,我想為這個鏈表編寫一些接口,可以不依賴於任何特定的類型,並且不需要我為每種數據類型聲明一個多余的函數。這種接口必然能涵蓋多種類型,我們稱它為GValue(Generic Value,泛型)。

要編寫一個泛型的屬性設置機制,我們需要一個將其參數化的方法,以及與實例結構體中的成員變量名查重的機制。從外部上看,我們希望使用C字符串來區分屬性和公有API,但是內部上來說,這樣做會嚴重的影響效率。因此我們枚舉化了屬性,使用索引來標識它們。
屬性規格,在Glib中被稱作!GParamSpec,它保存了對象的gtype,對象的屬性名稱,屬性枚舉ID,屬性默認值,邊界值等,類型系統用!GParamSpec來將屬性的字符串
名轉換為枚舉的屬性ID,GParamSpec也是一個能把所有東西都粘在一起的大膠水。
一個Closure是一個抽象的、通用表示的回調(callback)。它是一個包含三個對象的簡單結構:
(1)一個函數指針(回調本身) ,原型類似於:
return_type function_callback (... , gpointeruser_data);
(2) user_data指針用來在調用Closure時傳遞到callback。
(3)一個函數指針,代表Closure的銷毀:當Closure的引用數達到0時,這個函數將被調用來釋放Closure的結構。
一個GClosure提供以下簡單的服務:
調用(g_closure_invoke):這就是Closure創建的目的: 它們隱藏了回調者的回調細節。
通知:相關事件的Closure通知監聽者如Closure調用,Closure無效和Clsoure終結。監聽者可以用注冊g_closure_add_finalize_notifier(終結通知),g_closure_add_invalidate_notifier(無效通知)和g_closure_add_marshal_guards(調用通知)。
對於終結和無效事件來說,這是對等的函數(g_closure_remove_finalize_notifier和g_closure_remove_invalidate_notifier,但調用過程不是。
“一眼望穿”閉包
我們從分析g_signal_new函數的使用來說明這個問題。第7個參數為GSignalMarshaller類型,它與前面體面提到的GClosureMarshal是一個東西,都是一個函數指針。

GSignalCMarshallerc_marshaller:該參數是一個GSignalCMarshall類型的函數指針,其值反映了回調函數的返回值類型和額外參數類型(所謂“額外參數”,即指除回調函數中instance和user_data以外的參數)。
例如,g_closure_marshal_VOID_VOID說明該signal的回調函數為以下的callback類型:
typedef void (*callback) (gpointer instance, gpointer user_data);
而g_closure_marshal_VOID_POINTER則說明該signal的回調函數為以下的callback類型:
typedef void (*callback) (gpointer instance,gpointer arg1, gpointeruser_data);
GTypereturn_type:該參數的值應為回調函數的返回值在GType類型系統中的ID。
guintn_params:該參數的值應為回調函數的額外參數的個數。
...:這一系列的參數的值應為回調函數的額外參數在GType類型系統中的ID,且這一系列參數中第一個參數的值為回調函數的第一個額外參數在GType類型系統中的ID,依次類推。可以認為,信號就是包含對可以連接到信號的閉包的描述和對連接到信號的閉包的調用順序的規定的集合體。
事實上,它是用來翻譯閉包的參數和返回值類型的,它將翻譯的結果傳遞給閉包。之所以不直接調用callback或閉包,而在外面加了一層msrshal的封裝,主要是方便gobjec庫與其他語言的綁定。例如,我們可以寫一個pyg_closure_marshal_void_string函數,其中可以調用python語言編寫的“閉包”並將其計算結果傳遞給Gvalue容器,然后再從Gvalue容器中提取計算結果。

Gobject消息系統:Signal機制
(1)信號注冊,主要解決信號與數據類型的關聯問題
(2)信號連接,主要處理信號與閉包的連接問題;
(3)信號發射, 調用callback進行處理。
