2010-10-04 77 views
4

在GTK +調用中,參數應該(但不一定)從GtkWidget轉換爲函數在傳遞參數之前所需的最具體的類。例如,有時我看到函數參數的GTK +類型轉換樣式

some_call(GTK_WINDOW(window)); 

而其他時候,我看到

some_call((GtkWindow *) window); 

有什麼區別?

回答

2

第一個是一個宏既能測試是否鑄造是可能的,並且執行投。這是GTKs版本/類型安全演員的嘗試。你應該使用那個。

+0

正如我在對Amarghosh的回答的評論中所闡述的那樣,如果GTK +和co在它們的調試模式下編譯,這種強制宏只會測試強制轉換是否可行。如果它們以發佈模式編譯,那麼它們只是歸結爲「(GtkWhatever *)somePtr」。當然,使用宏_anyway_是一個好主意,這樣如果您使用GTK +的調試版進行編譯,您可以免費獲得支票,但值得強調的是,如果宏'鏈接到發佈版本。 – 2016-08-08 22:57:29

+0

爲了澄清,在您的書面程序中擴展了類型檢查宏。因此,來自「underscore_d」的評論是錯誤的。當然,鏈接到庫的發佈版本(所有發行版均附帶發行版編譯共享庫)。除非您沒有將COMPILE編譯爲發行版本,否則您仍然可以獲得完整的安全性。 – Lothar 2017-03-26 05:29:48

7

GTK_WINDOW是做演員的宏。

As seen here

#define GTK_WINDOW(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_WINDOW, GtkWindow)) 

Again

#define GTK_CHECK_CAST G_TYPE_CHECK_INSTANCE_CAST 

and

#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type)) 

which is...

#define _G_TYPE_CIC(ip,gt,ct) \ 
    ((ct*) g_type_check_instance_cast ((GTypeInstance*) ip, gt)) 

的代碼g_type_check_instance_castcan be found here

GTypeInstance* 
g_type_check_instance_cast (GTypeInstance *type_instance, 
          GType   iface_type) 
{ 
    if (type_instance) 
    { 
     if (type_instance->g_class) 
     { 
      TypeNode *node, *iface; 
      gboolean is_instantiatable, check; 

      node = lookup_type_node_I (type_instance->g_class->g_type); 
      is_instantiatable = node && node->is_instantiatable; 
      iface = lookup_type_node_I (iface_type); 
      check = is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE); 
      if (check) 
      return type_instance; 

      if (is_instantiatable) 
      g_warning ("invalid cast from `%s' to `%s'", 
         type_descriptive_name_I (type_instance->g_class->g_type), 
         type_descriptive_name_I (iface_type)); 
      else 
      g_warning ("invalid uninstantiatable type `%s' in cast to `%s'", 
         type_descriptive_name_I (type_instance->g_class->g_type), 
         type_descriptive_name_I (iface_type)); 
     } 
     else 
     g_warning ("invalid unclassed pointer in cast to `%s'", 
        type_descriptive_name_I (iface_type)); 
    } 

    return type_instance; 
} 
+1

這個答案的細節已過時,但總體思路可能類似......在調試模式下。這就是要點:爲了完全,這個答案應該澄清這個有用但肥胖的類型檢查 - 對於任何想要響應式GUI的人來說都是仁慈的 - 只有在調試模式下構建時才能完成,否則他們會做一個基本的'(Cast *)': 「_如果GTK +和GNOME是在禁用了widget調試的情況下編譯的,就像發佈版本一樣,這些強制轉換宏只做一個直接的C風格轉換,而沒有GTK +類型檢查和日誌消息的開銷。」http:// openbooks。 sourceforge.net/books/wga/gtk.html – 2016-08-08 22:43:16

+0

具體來說:'_G_TYPE_CIC'是基於GTK +和co的構建模式最終獲得'#define'd的不同。 – 2016-08-08 22:50:57

-3

GTK_WINDOW()僅僅是一個宏,它會是這個樣子:

#define GTK_WINDOW(a) ((GtkWindow*)a) 

這等同於自己做一個明確的轉換,你應該在兩個語句在您的文章是相同的。

+0

只有在發佈模式下編譯GTK +和co時,纔會出現這種情況。如果它們是以調試模式編譯的,則執行Amarghosh答案中顯示的類型檢查例程。所以你們每個人都畫了一半的照片。如果只有人做了兩個! – 2016-08-08 22:54:32