Most of the time classes are instantiatable. It can create "instances", which have their own data and share common methods of the class.
So a CLASS is shared by many INSTANCEs.
In GObject, we need two structs. One for the class and one for the instance.
/* A fundamental type. Instantiatable. */
#include <stdio.h>
#include <glib-object.h>
typedef struct {
GTypeClass something_as_boilerplate;
} myclass_t;
int a_class_member_of_myclass;
typedef struct {
GTypeInstance something_as_boilerplate; int an_instance_member;
} myinstance_t;
void my_class_method() {
printf("The class member is %d\n", a_class_member_of_myclass);
}
void my_instance_method(myinstance_t *instance, int a_parameter) {
printf("The member is %d\n",instance->an_instance_member);
printf("The parameter is %d\n",a_parameter);
}
void my_class_init_func(myclass_t* klass, gpointer data) {
printf("my_class_init_func called!\n");
a_class_member_of_myclass = 42;
}
void my_instance_init_func(myinstance_t *instance, gpointer data) {
printf("my_instance_init_func called!\n");
instance->an_instance_member = 65;
}
int main() {
g_type_init();
GTypeInfo my_type_info = {
sizeof(myclass_t), //guint16 class_size;
NULL, //GBaseInitFunc base_init;
NULL, //GBaseFinalizeFunc base_finalize;
/* classed types, instantiated types */
(GClassInitFunc)my_class_init_func, //GClassInitFunc class_init;
NULL, //GClassFinalizeFunc class_finalize;
NULL, //gconstpointer class_data;
/* instantiated types */
sizeof(myinstance_t),//guint16 instance_size;
0, //guint16 n_preallocs;
(GInstanceInitFunc)my_instance_init_func, //GInstanceInitFunc instance_init;
/* value handling */
NULL, //const GTypeValueTable *value_table;
};
GTypeFundamentalInfo my_fundamental_info = {
G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE
};
GType my_type_id = g_type_register_fundamental(
g_type_fundamental_next(),
"MyInstantiatableFundamentalType",
&my_type_info,
&my_fundamental_info,
0
);
printf("%d\n",my_type_id);
printf("%s\n",g_type_name(my_type_id));
myinstance_t *instance = (myinstance_t*)g_type_create_instance(my_type_id);
my_instance_method(instance,78);
my_class_method();
printf("Is instance of class? %s\n",
G_TYPE_CHECK_INSTANCE_TYPE(instance, my_type_id)?"yes":"no");
printf("Is instance of class? %s\n",
G_TYPE_CHECK_INSTANCE_TYPE(instance, G_TYPE_INT)?"yes":"no");
return 0;
}
And focus in here:
typedef struct {
GTypeClass something_as_boilerplate;
} myclass_t;
int a_class_member_of_myclass;
typedef struct {
GTypeInstance something_as_boilerplate;
int an_instance_member;
} myinstance_t;
Q: What are the something_as_boilerplate things?
A: As every other classes in GObject, all class structs start with a GTypeClass field and all instance structs start with a GTypeInstance field.
Q: What do they contain?
A: GTypeClass contains a GType which shows its type. GTypeInstance contains a pointer to its class struct so every instance knows its class. See the source code to make sure.
Q: Where are their members/fields?
A: Non-static members (such as an_instance_member) are in the instance struct, after the GTypeInstace. Static members (such as a_class_member_of_myclass) are usually global and are usually not in the class struct(see the previous article).
Q: How do you figure out if it is a member or a global variable?
A: You say "let it be a member" and it is a member. The concepts "object-oriented programming", "class", "instance" and "member" are all man-made so it is a member if you treat it like a member.
And the functions:
void my_class_method() {
printf("The class member is %d\n", a_class_member_of_myclass);
}
void my_instance_method(myinstance_t *instance, int a_parameter) {
printf("The member is %d\n",instance->an_instance_member);
printf("The parameter is %d\n",a_parameter);
}
Q: What are methods like?
A: Methods are simply functions. Non-static methods always take a pointer to an instance struct as their first parameter. Static methods are ordinary functions.
Q: How do you figure out if it is a member or a global variable?
A: You say "let it be a method" and it is a method. The concept "method" is man-made so it is a method if you treat it like a method.
Now we ask GLib to recognize my class as a type.
Code from the main() function:
GTypeInfo my_type_info = {
sizeof(myclass_t), //guint16 class_size;
NULL, //GBaseInitFunc base_init;
NULL, //GBaseFinalizeFunc base_finalize;
/* classed types, instantiated types */
(GClassInitFunc)my_class_init_func, //GClassInitFunc class_init;
NULL, //GClassFinalizeFunc class_finalize;
NULL, //gconstpointer class_data;
/* instantiated types */
sizeof(myinstance_t),//guint16 instance_size;
0, //guint16 n_preallocs;
(GInstanceInitFunc)my_instance_init_func, //GInstanceInitFunc instance_init;
/* value handling */
NULL, //const GTypeValueTable *value_table;
};
GTypeFundamentalInfo my_fundamental_info = {
G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE
};
GType my_type_id = g_type_register_fundamental(
g_type_fundamental_next(),
"MyInstantiatableFundamentalType",
&my_type_info,
&my_fundamental_info,
0
);
Again we use the g_type_register_fundamental() function to make the library think myclass is a class whose instance is myinstance.
We provide one GTypeInfo struct. class_size and instance_size are filled so that the library can automatically malloc a myclass_t struct and some myinstance_t structs. class_init and instance_init are also provided so that the library can help me initialize the class/instance struct when they are created.
In GTypeFundamentalInfo, mark my class as CLASSED and INSTANTIATABLE.
Register it with g_type_register_fundamental and then it becomes a type.
And the init functions:
void my_class_init_func(myclass_t* klass, gpointer data) {
printf("my_class_init_func called!\n");
a_class_member_of_myclass = 42;
}
void my_instance_init_func(myinstance_t *instance, gpointer data) {
printf("my_instance_init_func called!\n");
instance->an_instance_member = 65;
}
They initialize the class and the instance, respectively on creating. You can omit them if they are not necessary.
Now the main() function:
printf("%d\n",my_type_id);
printf("%s\n",g_type_name(my_type_id));
myinstance_t *instance = (myinstance_t*)g_type_create_instance(my_type_id);
my_instance_method(instance,78);
my_class_method();
printf("Is instance of class? %s\n",
G_TYPE_CHECK_INSTANCE_TYPE(instance, my_type_id)?"yes":"no");
printf("Is instance of class? %s\n",
G_TYPE_CHECK_INSTANCE_TYPE(instance, G_TYPE_INT)?"yes":"no");
g_type_name querys the string representation of the name of the type.
When first creating an instance using g_type_create_instance, the class struct is automatically allocated and initialized.
In order to call a instance method, just call the function with the first argument filled as the instance pointer.
G_TYPE_CHECK_INSTANCE_TYPE checks the type of an instance.
Q: How can it know the type of the instance by merely a pointer to the instance?
A: Recall that the first field of myinstance_t (that is GTypeInstance) contains a pointer which points to its class struct (myclass_t) which begins with a GTypeClass which has a GType field which identifies its type.
This means GObject provides runtime type information (RTTI) support which C++ classes do not usually have. Note that you need to #include<typeinfo> in C++ in order to use RTTI.
分享到:
相关推荐
利用本软件,c++开发者可以在不依赖c++编译器之外的任何工具的前提下,实现c++中类与类之间的解耦合(class A对象与class B对象之间的解耦合)。 本软件支持c++11并向后兼容(支持c++11及其后续版本)。 开发环境为...
UltiSnips C 片段有助于编写 GObject 代码 安装 这些片段使用 UltiSnips ( ) 所以你应该先安装和配置它。 我使用 Vundle ( ) 来管理 vim 插件,但这不是强制性的。 如果你使用 Vundle,你可以添加到你的 ~/.vimrc ...
本示例用于演示GObject创建新类,类的继承与重载。代码实现了shape和square类,继承关系为: square -> shape ->gobject 其中,square重载了shape类的info接口。
crystal-gobject:Crystal的gobject-introspection
8. 继承:GObject支持类的继承,通过g_type_class_ref()和g_type_class_peek()等函数可以访问父类的方法和属性。 9. 错误处理:GObject提供了一套错误系统,允许对象在遇到错误时发出错误信息,通过GError结构体和g...
GObject是GTK+库的核心组件,它为C语言提供了一种面向对象的编程模型。在GTK+和Gnome开发中,GObject系统是构建复杂、可扩展软件的基础。这个离线API手册包含了GObject框架的详细信息,对于理解并利用GObject进行...
The GObject base class Object instanciation Object memory management Reference count Weak References Reference counts and cycles Object properties Accessing multiple properties at once The ...
Groonga GObject 描述 Groonga的GObject包装器。 去做... 安装 Debian GNU / Linux 。 运行以下命令: % sudo apt-get install -V -y gir1.2-groonga libgroonga-gobject0 的Ubuntu 。 运行以下命令: % ...
Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍
3. **设置类属性**:通过`g_object_class_install_property`函数,你可以向类添加自定义属性。这些属性可以有默认值,也可以通过`g_object_set`和`g_object_get`函数进行设置和获取。 4. **实现接口**:GObject系统...
gtkforphp gobject扩展为GObject功能提供了语言绑定。 有关该库的文档和信息可以在找到 现在,这只不过是一个占位符。 您可以发送评论,补丁,问题 这仍然是实验性的扩展。 安装/配置 此扩展需要gtkforphp / glib...
码-对象反省码插件,用于基于GObject-Intropection构建库文档。要求Ruby / GObject-Introspection尝试一下 git clone ...
离线安装包,亲测可用
**Python3-pygobject3: GObject库的Python 3绑定** `python3-pygobject3` 是一个Python 3版本的绑定库,它允许Python程序员能够利用GObject库的功能,这是GNOME桌面环境的核心组件之一。GObject库是C语言编写的一个...
液化天然气LGI是基于gobject内省的动态Lua绑定到基于GObject的库。 它允许直接从Lua使用基于GObject的库。 已获得许可的许可,请参见LICENSE文件全文。 该项目的主页位于。 LGI经过测试,并与标准Lua 5.1,Lua 5.2,...
gir_ffi, 在运行时使用 FFI,为基于GObject的库自动生成绑定 GirFFI由 Matijs van Zuijlen描述使用GObject内省存储库的GNOME的ruby 绑定。状态 特性为基于任何gobject的库创建绑定。在运行时生成绑定。为选定方法...
GObjectClass parent_class; void (*boy_born)(void); }; GType boy_get_type(void); Boy *boy_new(void); guint boy_get_age(Boy *boy); void boy_set_age(Boy *boy, guint age); gchar *boy_get_name(Boy *boy...
离线安装包,亲测可用
GObjectClass parent_class; // 父类指针,指向GObjectClass void (*boy_born)(void); // 出生的方法指针 }; GType boy_get_type(void); Boy *boy_new(void); guint boy_get_age(Boy *boy); void boy_set_age...
avahi-gobject-0.6.25-11.el6.i686.rpm是centos工具包。