An interface is a class with multiple abstract methods. A class may implement one or more interfaces which means that the class provides all the abstract methods specified in the interfaces. This separates the behavior pattern from the actual implementation.
An interface cannot be instantiated. However, if a class implements an interface, then the interface can be extracted from an instance of that class.
The full code to be ignored for now:
/* A subclass of GObject implementing a interface. */
#include <stdio.h>
#include <glib-object.h>
/* My Interface */
typedef struct myinterface myinterface_t;
struct myinterface {
GTypeInterface something_as_boilerplate;
void (*greet)(void *instance);
};
GType get_my_interface_typeid() {
static my_type_id = 0;
if(my_type_id==0) {
GTypeInfo my_type_info = {
sizeof(myinterface_t), //class_size;
NULL, //base_init;
NULL, //base_finalize;
/* classed types, instantiated types */
NULL, //class_init;
NULL, //class_finalize;
NULL, //class_data;
/* instantiated types */
0, //instance_size;
0, //n_preallocs;
NULL, //instance_init;
/* value handling */
NULL, //value_table;
};
my_type_id = g_type_register_static(
G_TYPE_INTERFACE,
"MyInterface",
&my_type_info,
0
);
}
return my_type_id;
}
/* My Class */
typedef struct {
GObject something_as_boilerplate;
char* name;
} myinstance_t;
typedef struct {
GObjectClass something_as_boilerplate;
} myclass_t;
void say_hello(myinstance_t *instance) { // a method of myinstance
printf("Hello, %s!\n",instance->name);
}
void my_instance_init_func(myinstance_t *instance, gpointer data) {
instance->name = "blahblah";
}
void my_class_init_func(myclass_t* klass, gpointer data) {
}
void init_my_interface_on_my_class(myinterface_t* iface, gpointer iface_data) {
iface->greet = say_hello;
}
GType get_my_class_typeid() {
static my_type_id = 0;
if(my_type_id==0) {
GTypeInfo my_type_info = {
sizeof(myclass_t), //class_size;
NULL, //base_init;
NULL, //base_finalize;
/* classed types, instantiated types */
(GClassInitFunc)my_class_init_func, //class_init;
NULL, //class_finalize;
NULL, //class_data;
/* instantiated types */
sizeof(myinstance_t),//instance_size;
0, //n_preallocs;
(GInstanceInitFunc)my_instance_init_func, //instance_init;
/* value handling */
NULL, //value_table;
};
my_type_id = g_type_register_static(
G_TYPE_OBJECT,
"MyClass",
&my_type_info,
0
);
/* Add interface */
GInterfaceInfo my_interface_info = {
(GInterfaceInitFunc)init_my_interface_on_my_class, // interface_init
NULL, // interface_finalize
NULL, // interface_data
};
g_type_add_interface_static(
my_type_id,
get_my_interface_typeid(),
&my_interface_info
);
}
return my_type_id;
}
/* main function */
int main() {
g_type_init();
printf("Class type id: %d\n",get_my_class_typeid());
printf("Class type name: %s\n",g_type_name(get_my_class_typeid()));
printf("Interface type id: %d\n",get_my_interface_typeid());
printf("Interface type name: %s\n",g_type_name(get_my_interface_typeid()));
myinstance_t *instance = (myinstance_t*)g_object_new(
get_my_class_typeid(),NULL);
GObject *obj = g_object_new(g_object_get_type(),NULL);
GObject *objs[2] = {instance,obj};
int i;
for(i=0;i<2;i++) {
myinterface_t *iface = G_TYPE_INSTANCE_GET_INTERFACE(
objs[i],get_my_interface_typeid(),myinterface_t);
if(iface != NULL) {
iface->greet(instance);
} else {
printf("This object does not implement myinterface.\n");
}
}
return 0;
}
In GObject, you define an interface with a struct containing the abstract methods (represented by function pointers):
typedef struct myinterface myinterface_t;
struct myinterface {
GTypeInterface something_as_boilerplate;
void (*greet)(void *instance);
};
as well as the g_type_register_static function and specifys that it is a subclass of GInterface:
GType get_my_interface_typeid() {
static my_type_id = 0;
if(my_type_id==0) {
GTypeInfo my_type_info = {
sizeof(myinterface_t), //class_size;
NULL, //base_init;
NULL, //base_finalize;
/* classed types, instantiated types */
NULL, //class_init;
NULL, //class_finalize;
NULL, //class_data;
/* instantiated types */
0, //instance_size;
0, //n_preallocs;
NULL, //instance_init;
/* value handling */
NULL, //value_table;
};
my_type_id = g_type_register_static(
G_TYPE_INTERFACE,
"MyInterface",
&my_type_info,
0
);
}
return my_type_id;
}
A class implements an interface using the g_type_add_interface_static function just after the class type is registered into the GObject library using g_type_register_static. Note that only subclasses of the GObject class may implement interfaces.
GInterfaceInfo my_interface_info = {
(GInterfaceInitFunc)init_my_interface_on_my_class, // interface_init
NULL, // interface_finalize
NULL, // interface_data
};
g_type_add_interface_static(
my_type_id,
get_my_interface_typeid(),
&my_interface_info
);
}
The init_my_interface_on_my_class function (that is a GInterfaceInitFunc) is important. It specifies HOW a class implememts an interface. Whenever a class is said to implement an interface, this function is called and a new instance of the interface class struct (that is, "struct myinterface" in this program) is created and passed into this function. This function is supposed to override the abstract methods in this struct by providing the corresponding function pointers that overrides the abstract methods.
void init_my_interface_on_my_class(myinterface_t* iface, gpointer iface_data) {
iface->greet = say_hello;
}
You can extract the interface class (struct myinterface) from an instance of myclass. The macro G_TYPE_INSTANCE_GET_INTERFACE gets the specified interface struct fron an instance.
myinstance_t *instance = (myinstance_t*)g_object_new(
get_my_class_typeid(),NULL);
GObject *obj = g_object_new(g_object_get_type(),NULL);
GObject *objs[2] = {instance,obj};
int i;
for(i=0;i<2;i++) {
myinterface_t *iface = G_TYPE_INSTANCE_GET_INTERFACE(
objs[i],get_my_interface_typeid(),myinterface_t);
if(iface != NULL) {
iface->greet(instance);
} else {
printf("This object does not implement myinterface.\n");
}
}
Note that there is no compile-time type-checking on interface implementations. You have to know what class implements what interface. If a class does not implement the interface you specified, G_TYPE_INSTANCE_GET_INTERFACE will return NULL.
.NET languages like C# allows properties and events to appear in interfaces. You can do these too in GObject by utilizing the base_init function in the GTypeInfo struct for the interface type. However, as stated before, there is no compile-time type-checking on properties and signals.
分享到:
相关推荐
*) GObject::connect函数;开发者使用本函数,将发射者的信号连接到接收者的槽函数。连接成功后,发射者发射信号,接收者的槽函数将会被调用。 *) GObject::disconnect函数;开发者使用本函数,将发射者的信号与接收...
GTypePlugin - An interface for dynamically loadable types GTypeModule - Type loading modules GObject - The base object type Enums and Flags - Enumeration and flags types GBoxed - A mechanism to ...
UltiSnips C 片段有助于编写 GObject 代码 安装 这些片段使用 UltiSnips ( ) 所以你应该先安装和配置它。 我使用 Vundle ( ) 来管理 vim 插件,但这不是强制性的。 如果你使用 Vundle,你可以添加到你的 ~/.vimrc ...
crystal-gobject:Crystal的gobject-introspection
Groonga GObject 描述 Groonga的GObject包装器。 去做... 安装 Debian GNU / Linux 。 运行以下命令: % sudo apt-get install -V -y gir1.2-groonga libgroonga-gobject0 的Ubuntu 。 运行以下命令: % ...
Gobject 离线API手册
Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍
gtkforphp gobject扩展为GObject功能提供了语言绑定。 有关该库的文档和信息可以在找到 现在,这只不过是一个占位符。 您可以发送评论,补丁,问题 这仍然是实验性的扩展。 安装/配置 此扩展需要gtkforphp / glib...
本示例用于演示GObject创建新类,类的继承与重载。代码实现了shape和square类,继承关系为: square -> shape ->gobject 其中,square重载了shape类的info接口。
码-对象反省码插件,用于基于GObject-Intropection构建库文档。要求Ruby / GObject-Introspection尝试一下 git clone ...
对于学习glib很有用的资源啊,gobject很有用,多多支持~
离线安装包,亲测可用
gir_ffi, 在运行时使用 FFI,为基于GObject的库自动生成绑定 GirFFI由 Matijs van Zuijlen描述使用GObject内省存储库的GNOME的ruby 绑定。状态 特性为基于任何gobject的库创建绑定。在运行时生成绑定。为选定方法...
本示例演示Gobject类的创建、类属性设置、实例接口重载、类接口重载。带Makefile,可直接编译运行。
离线安装包,亲测可用
avahi-gobject-0.6.25-11.el6.i686.rpm是centos工具包。
液化天然气LGI是基于gobject内省的动态Lua绑定到基于GObject的库。 它允许直接从Lua使用基于GObject的库。 已获得许可的许可,请参见LICENSE文件全文。 该项目的主页位于。 LGI经过测试,并与标准Lua 5.1,Lua 5.2,...
离线安装包,亲测可用
离线安装包,亲测可用