Now I am going to create a classed type.
Q: What is a class?
A: I don't know for sure. In object-oriented programming, a class represents a "kind" of data. It specifies what data there is (the members/fields) in each object (instance) and what can be done (the methods) to the object.
Q: What is a "classed" type in GObject?
A: It is a type that has a "class struct".
Each "classed type" has a unique instance of "class structure". Note that IN GOBJECT, THERE IS A DIFFERENCE BETWEEN A "Class" AND AN "Instance". A "Class" IS SOMETHING THAT IS SHARED BY ALL OBJECTS OF A CLASS AND AN "Instance" IS SOMETHING THAT IS SPECIFIC TO EACH OBJECT OF THE CLASS. You can imagine that whatever in a "Class" are like the static members/fields in C++/Java and whatever in an "Instance" are like non-static members/fields.
The code is here:
/* A fundamental type. It has a class structure, but is not instantiable. */
#include <stdio.h>
#include <glib-object.h>
typedef struct {
GTypeClass something_as_boilerplate;
int foo;
char* bar;
void (*baz)();
} myclass_t;
void baz_function() { printf("All your type are belong to us!\n"); }
void my_class_init_func(myclass_t* klass, gpointer data) {
printf("my_class_init_func called!\n");
klass->foo = 42;
klass->bar = "Hello world!";
klass->baz = baz_function;
}
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 */
0, //guint16 instance_size;
0, //guint16 n_preallocs;
NULL, //GInstanceInitFunc instance_init;
/* value handling */
NULL, //const GTypeValueTable *value_table;
};
GTypeFundamentalInfo my_fundamental_info = {
G_TYPE_FLAG_CLASSED
};
GType my_type_id = g_type_register_fundamental(
g_type_fundamental_next(),
"MyClassedFundamentalType",
&my_type_info,
&my_fundamental_info,
0
);
printf("%d\n",my_type_id);
printf("%s\n",g_type_name(my_type_id));
myclass_t *klass = (myclass_t*)g_type_class_ref(my_type_id);
printf("foo: %d\n", klass->foo);
printf("bar: %s\n", klass->bar);
klass->baz();
g_type_class_unref(klass);
return 0;
}
Let's look at the my_type_info struct in the main function. I filled the class_size field to be sizeof(myclass_t) so that the type-system can help me "malloc" my myclass_t struct. I also filled the class_init function so that it will call my my_class_init_func to initialize it.
But I didn't fill the instance_size or instance_init so it is not instantiatable. That is, this type has no instances.
Q: How can it be it useful to have such a type that has no instances?
A: Well... I admit it is not that useful. It may work as something like a "singleton" (a globally unique object). Interfaces (like they are in Java/C#) in GObject are also non-instantiatable types.
Then the my_fundamental_info struct following the my_type_info variable in the main function. I marked this class as "classed".
Let's look at my myclass_t structure.
Q: Why don't you follow the GObject naming convention and name it as MyClass?
A: It is intentional. I am emphasizing that it is not the naming-convention, but the function calls (like g_type_register_fundamental) and its parameters (like GTypeInfo, GTypeFundamentalInfo and so on) that make GObject work. Yeah, you should follow the convention in real-world programming.
typedef struct {
GTypeClass something_as_boilerplate;
int foo; // Not a good idea to store data here.
char* bar;
void (*baz)();
} myclass_t;
The first member is a GTypeClass field. It is required that in GObject type system, all class-structs should begin with a GTypeClass field.
Q: What's inside the GTypeClass?
A: The documentation does not tell me. The source code is:
typedef struct _GTypeClass GTypeClass;
struct _GTypeClass
{
/*< private >*/
GType g_type;
};
So every class struct starts with a GType field (GType is typedef'ed to be gsize which is then typedef'ed to be unsigned int). This can be queryed at runtime to find the type-id (GType) of a type.
Then there are an int field "foo", a char pointer "bar" and a function pointer "baz" in myclass_t struct. foo and bar are static members of my class. baz, which you may think to be a static member, can also be a virtual method of a class (this will be discussed later).
Let's move on to the my_class_init_func which I filled into the class_init field of the "GTypeInfo my_type_info" struct.
void my_class_init_func(myclass_t* klass, gpointer data) {
printf("my_class_init_func called!\n");
klass->foo = 42;
klass->bar = "Hello world!";
klass->baz = baz_function;
}
It takes two parameters. One of them is a myclass_t pointer pointing to the struct to be initialized. I name it "klass" because "class" is a keyword in C++ and would not work with a C++ compiler. The other is the class_data field provided in the GTypeInfo struct (where I set it to NULL).
I initialized the myclass_t struct here. I filled the foo, bar and baz field.
Now the main function. Here I register my type. And then:
myclass_t *klass = (myclass_t*)g_type_class_ref(my_type_id);
printf("foo: %d\n", klass->foo);
printf("bar: %s\n", klass->bar);
klass->baz();
g_type_class_unref(klass);
I call the g_type_class_ref function so that my class struct is initialized. Then the members of klass are filled. Finally I call the g_type_class_unref(klass) to unref this class (this may be not necessary here).
Note that it is not a good idea to store static data member into the class struct. It is difficult to get a pointer to the class struct without having an instance of this class. You may wish to access the class member in the main function or in a static function. It is better to use global variables and use naming conventions to show that they belong to a class.
分享到:
相关推荐
利用本软件,c++开发者可以在不依赖c++编译器之外的任何工具的前提下,实现c++中类与类之间的解耦合(class A对象与class B对象之间的解耦合)。 本软件支持c++11并向后兼容(支持c++11及其后续版本)。 开发环境为...
Generic Values - A polymorphic type that can hold values of any other type Parameters and Values - Standard Parameter and Value Types Varargs Value Collection - Converting varargs to generic values ...
UltiSnips C 片段有助于编写 GObject 代码 安装 这些片段使用 UltiSnips ( ) 所以你应该先安装和配置它。 我使用 Vundle ( ) 来管理 vim 插件,但这不是强制性的。 如果你使用 Vundle,你可以添加到你的 ~/.vimrc ...
GObject是GTK+库的核心组件,它为C语言提供了一种面向对象的编程模型。在GTK+和Gnome开发中,GObject系统是构建复杂、可扩展软件的基础。这个离线API手册包含了GObject框架的详细信息,对于理解并利用GObject进行...
crystal-gobject:Crystal的gobject-introspection
8. 继承:GObject支持类的继承,通过g_type_class_ref()和g_type_class_peek()等函数可以访问父类的方法和属性。 9. 错误处理:GObject提供了一套错误系统,允许对象在遇到错误时发出错误信息,通过GError结构体和g...
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 资料,全面介绍
在IT领域,特别是软件开发中,GObject是一个关键的概念,它是GTK+库中的基础对象模型。GObject系统为C语言提供了面向对象编程的支持,而这个"gobject_setup_property_demo.zip"压缩包显然提供了一个关于如何使用...
gtkforphp gobject扩展为GObject功能提供了语言绑定。 有关该库的文档和信息可以在找到 现在,这只不过是一个占位符。 您可以发送评论,补丁,问题 这仍然是实验性的扩展。 安装/配置 此扩展需要gtkforphp / glib...
本示例用于演示GObject创建新类,类的继承与重载。代码实现了shape和square类,继承关系为: square -> shape ->gobject 其中,square重载了shape类的info接口。
码-对象反省码插件,用于基于GObject-Intropection构建库文档。要求Ruby / GObject-Introspection尝试一下 git clone ...
在使用任何GType或GObject之前,必须调用`g_type_init()`来初始化类型系统。`GType`提供了注册和管理所有基本数据类型、用户定义的对象和接口类型的技术实现。 ##### 2. 类型注册 (Type Registration) GObject支持...
3. **对象创建与实例化**:Python中的GObject子类可以像普通Python类一样实例化,但它们通常会调用`GObject.Object()`作为基类,并且可能需要通过`GObject.type_register`进行类型注册。 4. **属性和信号**:在...
离线安装包,亲测可用
为了确保类型系统的正确初始化,在使用任何`GType`或`GObject`的功能之前,必须调用`g_type_init()`函数。 - **静态类型与动态类型**: - **静态类型**:这些类型是在编译时确定的,不能在运行时动态地加载或卸载...
液化天然气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的库创建绑定。在运行时生成绑定。为选定方法...
离线安装包,亲测可用
avahi-gobject-0.6.25-11.el6.i686.rpm是centos工具包。