在GTK +調用中,參數應該(但不一定)從GtkWidget
轉換爲函數在傳遞參數之前所需的最具體的類。例如,有時我看到函數參數的GTK +類型轉換樣式
some_call(GTK_WINDOW(window));
而其他時候,我看到
some_call((GtkWindow *) window);
有什麼區別?
在GTK +調用中,參數應該(但不一定)從GtkWidget
轉換爲函數在傳遞參數之前所需的最具體的類。例如,有時我看到函數參數的GTK +類型轉換樣式
some_call(GTK_WINDOW(window));
而其他時候,我看到
some_call((GtkWindow *) window);
有什麼區別?
第一個是一個宏既能測試是否鑄造是可能的,並且執行投。這是GTKs版本/類型安全演員的嘗試。你應該使用那個。
GTK_WINDOW
是做演員的宏。
#define GTK_WINDOW(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_WINDOW, GtkWindow))
#define GTK_CHECK_CAST G_TYPE_CHECK_INSTANCE_CAST
#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type))
#define _G_TYPE_CIC(ip,gt,ct) \
((ct*) g_type_check_instance_cast ((GTypeInstance*) ip, gt))
的代碼g_type_check_instance_cast
can 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;
}
這個答案的細節已過時,但總體思路可能類似......在調試模式下。這就是要點:爲了完全,這個答案應該澄清這個有用但肥胖的類型檢查 - 對於任何想要響應式GUI的人來說都是仁慈的 - 只有在調試模式下構建時才能完成,否則他們會做一個基本的'(Cast *)': 「_如果GTK +和GNOME是在禁用了widget調試的情況下編譯的,就像發佈版本一樣,這些強制轉換宏只做一個直接的C風格轉換,而沒有GTK +類型檢查和日誌消息的開銷。」http:// openbooks。 sourceforge.net/books/wga/gtk.html – 2016-08-08 22:43:16
具體來說:'_G_TYPE_CIC'是基於GTK +和co的構建模式最終獲得'#define'd的不同。 – 2016-08-08 22:50:57
GTK_WINDOW()僅僅是一個宏,它會是這個樣子:
#define GTK_WINDOW(a) ((GtkWindow*)a)
這等同於自己做一個明確的轉換,你應該在兩個語句在您的文章是相同的。
只有在發佈模式下編譯GTK +和co時,纔會出現這種情況。如果它們是以調試模式編譯的,則執行Amarghosh答案中顯示的類型檢查例程。所以你們每個人都畫了一半的照片。如果只有人做了兩個! – 2016-08-08 22:54:32
正如我在對Amarghosh的回答的評論中所闡述的那樣,如果GTK +和co在它們的調試模式下編譯,這種強制宏只會測試強制轉換是否可行。如果它們以發佈模式編譯,那麼它們只是歸結爲「(GtkWhatever *)somePtr」。當然,使用宏_anyway_是一個好主意,這樣如果您使用GTK +的調試版進行編譯,您可以免費獲得支票,但值得強調的是,如果宏'鏈接到發佈版本。 – 2016-08-08 22:57:29
爲了澄清,在您的書面程序中擴展了類型檢查宏。因此,來自「underscore_d」的評論是錯誤的。當然,鏈接到庫的發佈版本(所有發行版均附帶發行版編譯共享庫)。除非您沒有將COMPILE編譯爲發行版本,否則您仍然可以獲得完整的安全性。 – Lothar 2017-03-26 05:29:48