C GTK&x2B;函数参数的类型转换样式

C GTK&x2B;函数参数的类型转换样式,c,gtk,C,Gtk,在GTK+调用中,在传递参数之前,应(但不必)将参数从GtkWidget强制转换为函数所需的最特定类。例如,有时我看到 some_call(GTK_WINDOW(window)); 而其他时候,我明白了 some_call((GtkWindow *) window); 有什么区别吗?GTK_WINDOW是一个执行强制转换的宏 g\u type\u check\u instance\u cast的代码 第一个是一个宏,它既可以测试强制转换是否可行,也可以执行强制转换。这是GTKs版本/

在GTK+调用中,在传递参数之前,应(但不必)将参数从
GtkWidget
强制转换为函数所需的最特定类。例如,有时我看到

some_call(GTK_WINDOW(window));
而其他时候,我明白了

some_call((GtkWindow *) window);

有什么区别吗?

GTK_WINDOW
是一个执行强制转换的宏

g\u type\u check\u instance\u cast的代码


第一个是一个宏,它既可以测试强制转换是否可行,也可以执行强制转换。这是GTKs版本/类型安全转换的尝试。您应该使用它。

GTK_WINDOW()只是一个看起来像这样的宏:

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

这与你自己做一个明确的演员阵容是一样的,你应该在你的帖子中做的两个陈述也是一样的。

这个答案的细节已经过时了,但总体思路可能是相似的。。。在调试模式下。这就是问题所在:为了完整起见,这个答案应该澄清这个有用但过于复杂的类型检查——幸运的是,对于任何想要响应GUI的人来说——只有在调试模式下构建时才能完成,否则他们会执行基本的
(Cast*)
:“如果GTK+和GNOME是在禁用小部件调试的情况下编译的,就像发行版一样,强制转换宏只执行直接的C风格强制转换,没有GTK+类型检查和日志消息的开销。“具体地说:
\u G_TYPE_CIC
是根据GTK+和co的构建模式最终得到的
\define
d不同。只有在发布模式下编译GTK+和co时才是如此。如果改为在调试模式下编译,则执行Amarghosh答案中显示的类型检查例程。所以你们每个人都画了一半。要是有人两样都做就好了!正如我在对Amarghosh答案的评论中所阐述的那样,这种强制转换宏只测试在GTK+和co以调试模式编译时是否可以进行强制转换。如果它们是在发布模式下编译的,那么它们只能归结为
(GtkWhatever*)somePtr
。当然,无论如何使用宏都是一个好主意,这样你就可以在编译GTK+的调试版本时免费获得检查,但值得强调的是,如果人们链接到发布版本,宏并不会让他们免于自食其果。只是澄清一下,类型检查宏在您编写的程序中展开。因此,“下划线”的注释是错误的。当然,链接到库的发布版本是很好的(所有发行版都附带发布编译的共享库)。您仍然可以获得完整的类型安全性,除非您没有编译到发布版本
#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))
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;
}
#define GTK_WINDOW(a) ((GtkWindow*)a)