gobject物件不宜作為動態載入的外掛程式

2021-04-17 14:25:57 字數 946 閱讀 8408

前段時間對 syncmanager進行重構,為了減少不必要的開銷,我決定在需要時才加syncsource外掛程式,不需要時就解除安裝它們。在測試時發現第一次執行時正 常,第二次執行時建立dbpersistance物件時失敗了。仔細看了下除錯資訊,裡面告訴我說註冊dbpersistance型別失敗,因為已經 dbpersistance型別註冊了。不太可能啊,物件註冊型別時一般都會防止重複註冊的,比如:

gtk_button_get_type (

void)

這裡的button_type靜態變數可以防止型別重複註冊,大家都是按種方式處理的,難道dbpersistance的註冊函式有什麼特殊嗎?看了一下**,果然有點不同:

g_define_type (dbpersistance, db_persistance, g_type_object)

它用glib提供的巨集實現的,再看看g_define_type的定義,展開出來的**也差不多。沒有什麼線索,只好用gdb跟到裡面看一下。發現g_define_type_id這個靜態變數第二次進去時還是0,回憶一下對**所做的改動,一下明白了其中的原理。

這個外掛程式是個動態庫,第 一次執行時,先載入它,然後呼叫bpersistance_get_type, g_define_type_id確實被初始化了,用完之後它被解除安裝了。 第二次執行時,這個外掛程式重新被載入,動態庫中的bss段被清零,g_define_type_id自然被初始化為0了,而管理gobject的物件系統是 放在malloc分配出來的堆裡面,它是一直存在的,只是裡面的資料有些是無效的。結果呼叫dbpersistance_get_type時,就會出現重 復註冊的問題。

gobject並沒有提供登出型別的介面,即使有這樣的介面也很麻煩,外掛程式要知道自己何時被解除安裝,並登出外掛程式中的全部型別(這個很難做到)。為了解決這個問題,我只好在編譯時鏈結相關的動態庫,在某種程度上說這失去了外掛程式的意義,但也沒有想到好的辦法。

看來在這種情況下,最好是避免使用gobject。

GObject物件系統

簡單的說,gobject物件系統是乙個建立在glib基礎上的,用c語言完成的,具有跨平台特色的 靈活的 可擴充套件的 非常容易對映到其它語言的物件導向的框架。如果你是乙個c語言的執著的追隨者,你沒有理由不研究一下它。前言 大多數現代的計算機語言都帶有自己的型別和物件系統,並附帶演算法結構。正象gli...

GObject物件系統 3

在gobject系統中,訊號是一種定製物件行為的手段,同時也是一種多種用途的通知機制。初學者可能是在gtk 中首先接觸到訊號這一概念的,事實上在普通的字元介面程式設計中也可以正常應用,這可能是很多初學者未曾想到的。乙個物件可以沒有訊號,也可以有多個訊號。當有一或多個訊號時,訊號的名稱定義是必不可少的...

物件作為引數

在這個例子中,我們將isequal 功能是價值流的乙個朋友。isequal 取兩個值物件作為引數。因為isequal 是價值類的朋友,它可以訪問所有的值物件的私有成員。在這種情況下,它使用的訪問在兩個物件做乙個比較,並返回true,如果他們是平等的。乙個函式可以同時對多個類的乙個朋友。例如,考慮下面...