- 浏览: 129831 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
cloverprince:
z707208280 写道写多表查询咋整? select 列 ...
[自己动手]用Java的反射实现DAO -
z707208280:
写多表查询咋整? select 列 这里用别名.字段 这咋整手 ...
[自己动手]用Java的反射实现DAO -
亮亮婷婷:
4楼正解,顶!
能在Eclipse 3.7中给m2e提供WTP支持的插件在哪里? -
cloverprince:
沙舟狼客 写道貌似2b青年的代码很有技术含量嗯,简单问题复杂化 ...
普通青年 文艺青年 2B青年 -
沙舟狼客:
貌似2b青年的代码很有技术含量
普通青年 文艺青年 2B青年
My coding style has been so weird that no proper GObject programmers would ever use.
GObject do have their coding/naming convention which is "designed by both smart and experienced people" and I am supposed "to put my ego aside".
Here are the official document about the "conventions":
:: http://library.gnome.org/devel/gobject/stable/gtype-conventions.html
-----------------------
Here is a minimal working example that is compliant to the coding convention. Yes, it compiles and runs! I admit I had a hard time making my first GObject program running. These code is mostly based on the "boilerplate" examples in the official GObject reference.
Comments omitted for cleanness and minimality.
Save this as maman-bar.h:
Save this as maman-bar.c:
Save this as main.c:
Compile with:
gcc $(pkg-config --cflags --libs gobject-2.0) *.c -o main
There should be no warnings or errors.
------------------------
Let's now have a look at our code.
We are creating a class named Bar in the namespace "Maman". Quite different from how we would define a class in C++:
we instead follow the "convention" of GObject. Convention is important since we are writing in C. There is no language-level notion of "object", "type", "class", "instance", "type-id", "dynamic type casting", "runtime type query", "runtime membership checking" or all other object-oriented buzzwords.
Remember how we "define" a class in GObject? (see http://cloverprince.iteye.com/blog/498390 if you don't) We register our new class with the g_type_register_static function, passing a filled GTypeInfo struct and some other parameters into it and it is done. After this, GObject will recognize our new class.
How could we define a class in a "convention"-compliant way? Let's look at our maman-bar.c. There is a macro:
See the reference about how to use it.
This will expand to (almost):
You could apply the -E option of gcc to see yourself.
It generates a function named maman_bar_get_type. Our new type-id is stored as a static variable. During the first time we call this function, it will be initialized. On subsequent calls, this type-id will be simply returned.
Such a function is always (by convention) named <namespace>_<classname>_get_type and takes no argument.
Also in maman-bar.c, there are:
What are they? They are initializer functions, much like "constructors" in C++. Well, you could omit the "constructor" in C++. Actually you COULD omit those init functions if you do not use the G_DEFINE_TYPE macro and register your type with g_type_register_static by yourself. Since we are using G_DEFINE_TYPE, we need to supply them.
By the way, initializing functions are (by convention) named <namespace>_<class>_init and <namespace>_<class>_class_init for instance init function and class init function, respectively. See my previous articles if you are not familiar with these concepts.
The complete maman-bar.c should look like this:
The above maman-bar.c implements the class. Now we need an interface to the outer world so that other people could use our class.
Just look into the well-commented version of maman-bar.h:
In the main.c, #include the maman-bar.h to use this class. Don't forget to call g_type_init(), which is required by all GObject-related libraries.
Summerize:
In order to define and use a class, you:
GObject do have their coding/naming convention which is "designed by both smart and experienced people" and I am supposed "to put my ego aside".
Here are the official document about the "conventions":
:: http://library.gnome.org/devel/gobject/stable/gtype-conventions.html
-----------------------
Here is a minimal working example that is compliant to the coding convention. Yes, it compiles and runs! I admit I had a hard time making my first GObject program running. These code is mostly based on the "boilerplate" examples in the official GObject reference.
Comments omitted for cleanness and minimality.
Save this as maman-bar.h:
#ifndef __MAMAN_BAR_H__ #define __MAMAN_BAR_H__ #include <glib-object.h> #define MAMAN_TYPE_BAR (maman_bar_get_type ()) #define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar)) #define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR)) #define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass)) #define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR)) #define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass)) typedef struct _MamanBar MamanBar; typedef struct _MamanBarClass MamanBarClass; struct _MamanBar { GObject parent_instance; }; struct _MamanBarClass { GObjectClass parent_class; }; GType maman_bar_get_type (void); #endif /* __MAMAN_BAR_H__ */
Save this as maman-bar.c:
#include "maman-bar.h" G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT); static void maman_bar_init (MamanBar *self) { } static void maman_bar_class_init (MamanBarClass *klass) { }
Save this as main.c:
#include <glib-object.h> #include "maman-bar.h" int main() { g_type_init(); /* NOTE: Don't forget this!!!! */ MamanBar *bar = g_object_new(MAMAN_TYPE_BAR, NULL); g_object_unref(bar); return 0; }
Compile with:
引用
gcc $(pkg-config --cflags --libs gobject-2.0) *.c -o main
There should be no warnings or errors.
------------------------
Let's now have a look at our code.
We are creating a class named Bar in the namespace "Maman". Quite different from how we would define a class in C++:
namespace Maman { class Bar : public GObject { ... }; }
we instead follow the "convention" of GObject. Convention is important since we are writing in C. There is no language-level notion of "object", "type", "class", "instance", "type-id", "dynamic type casting", "runtime type query", "runtime membership checking" or all other object-oriented buzzwords.
Remember how we "define" a class in GObject? (see http://cloverprince.iteye.com/blog/498390 if you don't) We register our new class with the g_type_register_static function, passing a filled GTypeInfo struct and some other parameters into it and it is done. After this, GObject will recognize our new class.
How could we define a class in a "convention"-compliant way? Let's look at our maman-bar.c. There is a macro:
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT);
See the reference about how to use it.
This will expand to (almost):
static void maman_bar_init(MamanBar * self); static void maman_bar_class_init(MamanBarClass * klass); static gpointer maman_bar_parent_class = ((void *) 0); static void maman_bar_class_intern_init(gpointer klass) { maman_bar_parent_class = g_type_class_peek_parent(klass); maman_bar_class_init((MamanBarClass *) klass); } GType maman_bar_get_type(void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter(&g_define_type_id__volatile)) { GType g_define_type_id = g_type_register_static_simple(((GType) ((20) << (2))), g_intern_static_string ("MamanBar"), sizeof(MamanBarClass), (GClassInitFunc) maman_bar_class_intern_init, sizeof(MamanBar), (GInstanceInitFunc) maman_bar_init, (GTypeFlags) 0); { { { }; } } g_once_init_leave(&g_define_type_id__volatile, g_define_type_id); } }
You could apply the -E option of gcc to see yourself.
It generates a function named maman_bar_get_type. Our new type-id is stored as a static variable. During the first time we call this function, it will be initialized. On subsequent calls, this type-id will be simply returned.
Such a function is always (by convention) named <namespace>_<classname>_get_type and takes no argument.
Also in maman-bar.c, there are:
static void maman_bar_init (MamanBar *self) { } static void maman_bar_class_init (MamanBarClass *klass) { }
What are they? They are initializer functions, much like "constructors" in C++. Well, you could omit the "constructor" in C++. Actually you COULD omit those init functions if you do not use the G_DEFINE_TYPE macro and register your type with g_type_register_static by yourself. Since we are using G_DEFINE_TYPE, we need to supply them.
By the way, initializing functions are (by convention) named <namespace>_<class>_init and <namespace>_<class>_class_init for instance init function and class init function, respectively. See my previous articles if you are not familiar with these concepts.
The complete maman-bar.c should look like this:
/* * Copyright information */ /* Include the header file (see below) */ #include "maman-bar.h" G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT); static void maman_bar_init (MamanBar *self) { /* TODO: Initialize *self here */ } static void maman_bar_class_init (MamanBarClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); /* TODO: Initialize *klass here */ }
The above maman-bar.c implements the class. Now we need an interface to the outer world so that other people could use our class.
Just look into the well-commented version of maman-bar.h:
/* * Copyright/Licensing information. */ /* Inclusion guard. * So that this header file will be included twice. */ #ifndef __MAMAN_BAR_H__ #define __MAMAN_BAR_H__ #include <glib-object.h> /* * TODO: Potentially, include other headers on which this header depends. */ /* * Type macros. * * What are they? * * They are not mandatory. I deliberately omitted them in my * previous articles in order to show their unnecessity. * However, other GObject programmers are expecting me to * provide these CONVENIENCE macros. I could also safely assume * that other (properly written) GObject programs provide * similar macros, too. */ /* This macro returns the type-id. It just call the maman_bar_get_type() */ #define MAMAN_TYPE_BAR (maman_bar_get_type ()) /* This macro casts obj (an instance) to this type. * Run-time type checking is performs to make sure the conversion * is successful. */ #define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar)) /* This macro checks whether obj (an instance) is an instance of * MamanBar or its derived classes. */ #define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR)) /* These two macros are similar, but for classes, not instances. */ #define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass)) #define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR)) /* This macro obtains the class struct (MamanBarClass) from obj (an instance). */ #define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass)) /* typedef the instance struct and class struct. By convention, * these two struct types are named in PascalCase and accessed * without the "struct" keyword. */ typedef struct _MamanBar MamanBar; typedef struct _MamanBarClass MamanBarClass; /* The actual instance struct. */ struct _MamanBar { GObject parent_instance; /* TODO: Add instance members (member variables) here. */ }; /* The actual class struct. */ struct _MamanBarClass { GObjectClass parent_class; /* TODO: Add class members (virtual member functions) here. */ }; /* used by MAMAN_TYPE_BAR */ GType maman_bar_get_type (void); /* * TODO: Add method definitions. */ #endif /* __MAMAN_BAR_H__ */
In the main.c, #include the maman-bar.h to use this class. Don't forget to call g_type_init(), which is required by all GObject-related libraries.
Summerize:
In order to define and use a class, you:
- Define the .h file, which includes an instance struct, a class struct, some convenience macros and prototypes of member functions. (Copy and paste the boilerplate is not a sin. Some code-generators also work well.)
- Define the .c file, which #include the .h file, uses the G_DEFINE_TYPE macro, and defines the two init functions.
- Call g_type_init() in main().
- #include the .h file and use it.
发表评论
-
GObject 09: An Interface
2009-11-09 16:56 1916An interface is a class with mu ... -
GObject 08: A class with a signal
2009-10-22 17:09 2615A GObject may emit signals to s ... -
GObject 07: A class with properties.
2009-10-22 16:17 1957A good practice of Object-orien ... -
GObject 06: A subclass of GObject
2009-10-21 13:44 1729This time GObject refers to the ... -
GObject 05: An Inheritable class.
2009-10-21 01:32 1999In this article I will implemen ... -
GObject 04: A class with private members
2009-10-21 00:49 1912A private member is a member th ... -
GObject 03: An Instantiatable Class
2009-10-16 16:35 1823Most of the time classes are in ... -
GObject 02: A classed type
2009-10-13 16:53 1803Now I am going to create a clas ... -
GObject 01: My first fundamental type.
2009-10-13 01:25 1868GObject system handles "ty ... -
GObject 00: A bottom-up introduction to the GObject system
2009-10-13 00:34 2169This document introduces the GO ...
相关推荐
FairyGUI is a flexible UI framework for Unity, working with the professional FREE Game UI Editor: FairyGUI Editor. Download the editor from here: http://en.fairygui.com/ -------------------- Get ...
离线安装包,亲测可用
离线安装包,亲测可用
官方离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
avahi-gobject-0.6.25-11.el6.i686.rpm是centos工具包。
5. libglib-2.0-0.dll:这是GObject库的一部分,GObject是GTK+的基础组件,提供了数据类型、内存管理、线程、事件循环等核心功能。libglib也是许多其他GNOME项目的基础。 6. libgio-2.0-0.dll:这是GTK+的I/O和网络...
要求Ruby / GObject-Introspection尝试一下 git clone https://github.com/ruby-gnome2/yard-gobject-introspectioncd yard-gobject-introspectionyard doc --load lib/yard-gobject-introspection.rb ~/.gem/ruby/2...
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
离线安装包,亲测可用
crystal-gobject:Crystal的gobject-introspection
官方离线安装包,亲测可用
官方离线安装包,亲测可用