C 和 GTK 传递参数
C and GTK Passing parameters
以下程序将无法编译。我已将代码缩减为这个简单的程序。我已经发布了编译命令及其输出。
#include <gtk/gtk.h>
void update_label(GtkLabel *glab);
void update_label(GtkLabel *glab)
{
}
int main(int argc, char *argv[])
{
GtkWidget *lbl;
gtk_init(&argc, &argv);
lbl = gtk_label_new("Hi");
update_label(lbl);
gtk_main();
return 0;
}
编译器输出为:
graeme@graeme-HP-xw4300-Workstation ~/c/label $ gcc `pkg-config --cflags gtk+-3.0` my04.c -o my04 `pkg-config --libs gtk+-3.0`
my04.c: In function ‘main’:
my04.c:17:3: warning: passing argument 1 of ‘update_label’ from incompatible pointer type [enabled by default]
update_label(lbl);
^
my04.c:5:6: note: expected ‘struct GtkLabel *’ but argument is of type ‘struct GtkWidget *’
void update_label(GtkLabel *glab)
^
您声明 update_label
接受 GtkLabel*
参数:
void update_label(GtkLabel *glab);
另一方面,您将参数 lbl
传递给它 GtkWidget*
:
GtkWidget *lbl;
(...)
update_label(lbl);
这就是编译器引发错误 "passing argument 1 of ‘update_label’ from incompatible pointer type" 的原因,甚至进一步解释:
my04.c:5:6: note: expected ‘struct GtkLabel *’ but argument is of type ‘struct GtkWidget *’
void update_label(GtkLabel *glab)
要解决这个问题,您必须将 lbl
向上转换为 GtkLabel*
,因为该变量指向的对象实际上是 GtkLabel
:
update_label(GTK_LABEL(lbl));
https://developer.gnome.org/gobject/stable/gtype-conventions.html
对于 C 中的 GTK,您需要大量的指针转换。
由于某种原因,所有创建者函数 return GtkWidget*
但所有相关的修饰函数都需要适当的指针指向 GtkLabel*
等。
为此,GTK 提供了类型转换宏。
您可以使用GTK_LABEL()
宏来转换您的指针。
对于其他类型的小部件,您有 GTK_WINDOW
、GTK_MENU_ITEM
和更多此类宏。
首先这很烦人。
当涉及来自接口或父对象的函数时 "class"(不是真正的 OO 类),您需要选择正确的类型并进行适当的转换。
以下程序将无法编译。我已将代码缩减为这个简单的程序。我已经发布了编译命令及其输出。
#include <gtk/gtk.h>
void update_label(GtkLabel *glab);
void update_label(GtkLabel *glab)
{
}
int main(int argc, char *argv[])
{
GtkWidget *lbl;
gtk_init(&argc, &argv);
lbl = gtk_label_new("Hi");
update_label(lbl);
gtk_main();
return 0;
}
编译器输出为:
graeme@graeme-HP-xw4300-Workstation ~/c/label $ gcc `pkg-config --cflags gtk+-3.0` my04.c -o my04 `pkg-config --libs gtk+-3.0`
my04.c: In function ‘main’:
my04.c:17:3: warning: passing argument 1 of ‘update_label’ from incompatible pointer type [enabled by default]
update_label(lbl);
^
my04.c:5:6: note: expected ‘struct GtkLabel *’ but argument is of type ‘struct GtkWidget *’
void update_label(GtkLabel *glab)
^
您声明 update_label
接受 GtkLabel*
参数:
void update_label(GtkLabel *glab);
另一方面,您将参数 lbl
传递给它 GtkWidget*
:
GtkWidget *lbl;
(...)
update_label(lbl);
这就是编译器引发错误 "passing argument 1 of ‘update_label’ from incompatible pointer type" 的原因,甚至进一步解释:
my04.c:5:6: note: expected ‘struct GtkLabel *’ but argument is of type ‘struct GtkWidget *’
void update_label(GtkLabel *glab)
要解决这个问题,您必须将 lbl
向上转换为 GtkLabel*
,因为该变量指向的对象实际上是 GtkLabel
:
update_label(GTK_LABEL(lbl));
https://developer.gnome.org/gobject/stable/gtype-conventions.html
对于 C 中的 GTK,您需要大量的指针转换。
由于某种原因,所有创建者函数 return GtkWidget*
但所有相关的修饰函数都需要适当的指针指向 GtkLabel*
等。
为此,GTK 提供了类型转换宏。
您可以使用GTK_LABEL()
宏来转换您的指针。
对于其他类型的小部件,您有 GTK_WINDOW
、GTK_MENU_ITEM
和更多此类宏。
首先这很烦人。
当涉及来自接口或父对象的函数时 "class"(不是真正的 OO 类),您需要选择正确的类型并进行适当的转换。