Gobject编程实现
来源:互联网 发布:python 财经数据接口 编辑:程序博客网 时间:2024/06/02 06:46
GObject 是一个程序库,它可以帮助我们使用 C 语言编写面向对象程序。
GObject实现有一套固有的格式,可以理解为C++语言的语法一样,如果要使用GObject就必须按格式实现。
GObject的对象系统提供了一种灵活的、可扩展的、并容易映射(到其它语言)的单根继承面向对象的C语言框架。
animal-base.h的实现如下:
#ifndef _BASE_H_#define _BASE_H_#include <glib-object.h>#include <stdio.h>typedef struct _AnimalBase AnimalBase;typedef struct _AnimalBaseClass AnimalBaseClass;#define ANIMAL_TYPE_BASE (animal_base_get_type())//实例类型转换#define ANIMAL_BASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ANIMAL_TYPE_BASE, AnimalBase))//实例类型判定#define ANIMAL_IS_BASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ANIMAL_TYPE_BASE))//类结构转换#define ANIMAL_BASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ANIMAL_TYPE_BASE, AnimalBaseClass))//类结构判定#define ANIMAL_IS_BASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ANIMAL_TYPE_BASE))//获取类结构#define ANIMAL_BASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ANIMAL_TYPE_BASE, AnimalBaseClass))struct _AnimalBase{GObject parent;char szName[32];//名称intiEye;//眼睛个数intiNose;//鼻子个数intiMouth; //嘴巴intiLeg; //腿intiTail; //尾巴};struct _AnimalBaseClass{GObjectClass classparent;void (*drinkwater)(AnimalBase *obj);void (*eat)(AnimalBase *obj);void (*run)(AnimalBase *obj);};void send_base_drink_signal(AnimalBase *pBase);#endif
animal-base.c的实现如下:
#include "animal-base.h"#include <string.h>typedef enum{DRINK_BASE_SIGNAL = 0,EAT_BASE_SIGNAL = 1,RUN_BASE_SIGNAL = 2,LAST_BASE_SIGNAL};static int basesignals[LAST_BASE_SIGNAL];G_DEFINE_TYPE(AnimalBase,animal_base,G_TYPE_OBJECT);static void animal_base_init(AnimalBase *pBase){printf("animal_base_init.\n");}static void animal_base_class_destroy(GObject *object){printf("animal_base_class_destroy.\n");}static void animal_base_class_finalize(GObject *object){printf("animal_base_class_finalize.\n");}static void animal_base_drink(AnimalBase *pBase){printf("animal_base_drink[%p] class[%p].\n",pBase,ANIMAL_BASE_GET_CLASS(pBase));}static void animal_base_eat(AnimalBase *pBase){printf("animal_base_eat[%p].\n",pBase);}static void animal_base_run(AnimalBase *pBase){printf("animal_base_run[%p].\n",pBase);}static void animal_base_class_init(AnimalBaseClass *pBaseClass){G_OBJECT_CLASS(pBaseClass)->finalize = animal_base_class_finalize;G_OBJECT_CLASS(pBaseClass)->dispose = animal_base_class_destroy;pBaseClass->drinkwater = animal_base_drink;pBaseClass->eat = animal_base_eat;pBaseClass->run = animal_base_run;basesignals[DRINK_BASE_SIGNAL] = g_signal_new ("basedrink", G_TYPE_FROM_CLASS (pBaseClass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (AnimalBaseClass, drinkwater), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);printf("animal_base_class_init.\n");}void send_base_drink_signal(AnimalBase *pBase){g_signal_emit (pBase, basesignals[DRINK_BASE_SIGNAL], 0);}
在GObject系统中,对象由三个部分组成:
- 对象的ID标识(唯一,无符号长整型,所有此类对象共同的标识);
- 对象的类结构(唯一,结构型,由对象的所有实例共同拥有);
- 对象的实例(多个,结构型,对象的具体实现)。
在Gobject中每个对象需要使用两个结构体描述,一个类结构体AnimalBaseClass,一个实例结构体AnimalBase。创建多个对象时类结构体只会有一个,实例结构体则有多少个对象则有多少个实例。当第一次创建对象时,没有新建类结构体则会先新建类结构体并调用类结构体的初始化函数animal_base_class_init再新建实例结构体调用实例结构体的初始化函数animal_base_init,如果已经之前已经新建过类结构体则不再新建类结构体直接新建实例结构体。
#define P_TYPE_T (p_t_get_type ())#define P_T(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), P_TYPE_T, PT))#define P_IS_T(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), P_TYPE_T))#define P_T_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), P_TYPE_T, PTClass))#define P_IS_T_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), P_TYPE_T))#define P_T_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), P_TYPE_T, PTClass))
这些宏的用法总结如下:
- P_TYPE_T:仅在使用 g_object_new 进行对象实例化的时候使用一次,用于向 GObject 库的类型系统注册 PT 类;
- P_T (obj):用于将 obj 对象的类型强制转换为 P_T 类的实例结构体类型;
- P_IS_T (obj):用于判断 obj 对象的类型是否为 P_T 类的实例结构体类型;
- P_T_CLASS(klass):用于将 klass 类结构体的类型强制转换为 P_T 类的类结构体类型;
- P_IS_T_CLASS(klass):用于判断 klass 类结构体的类型是否为 P_T 类的类结构体类型;
- P_T_GET_CLASS(obj):获取 obj 对象对应的类结构体类型。
以上代码实现之后,Gobject的对象已经实现了,接下来就是在代码中需要的时候如何new出一个对象,调用函数g_object_new
#include "animal-base.h" int main (void) { AnimalBase *P0 = NULL;AnimalBase *P1 = NULL;AnimalBase *P2 = NULL; g_type_init (); P0 = g_object_new (ANIMAL_TYPE_BASE, NULL); P1 = g_object_new (ANIMAL_TYPE_BASE, NULL); P2 = g_object_new (ANIMAL_TYPE_BASE, NULL);printf("start send signal.\n"); send_base_drink_signal(P0); send_base_drink_signal(P1); send_base_drink_signal(P2);printf("end send signal.\n");g_object_unref(P0);g_object_unref(P1);g_object_unref(P2); return 0; }
gpointer
g_object_new (GType object_type,
const gchar *first_property_name,
...)
这个函数是个可变参数的函数, 第一个参数是需要创建的对象的类型, 当使用 g_object_new 来创建对象的时候, 这个参数是必须的, 同时它还要求这个函数所创建 的对象必须是GObject的子对象. 在我们定义自己的对象时, 必须要在系统中注册自己的 类型, 这里的系统指的是 glib 的系统。
编译命令为:gcc -Wall Base.c main.c -o test $(pkg-config --cflags --libs gobject-2.0)
上面main函数运行的结果如下:
- Gobject编程实现
- glib 编程2-gobject
- GObject-GSignal实现
- GObject
- GObject
- gobject
- gobject
- GObject
- GObject
- GObject接口定义和实现
- 如何定义和实现新的GObject之代码实现
- GObject 参考手册:教程:如何定义和实现接口
- 定义、注册和实现 GObject 类的子类
- GObject:用C实现类是如何做到的
- 如何定义和实现新的GObject之对象方法
- gobject instantiation
- GObject Tutorial
- 学习GObject
- Log4j使用笔记(二):每天生成一个日志文件、按日志大小生成文件
- position为absolute的居中问题
- windows下Mysql5.7.11免安装模式下不能无密登录 Access denied for user 'root'@'localhost' (using password: NO)
- Nginx 1.10.1 版本nginx.conf优化配置及详细注释
- 阿里云ECS 部署 LAMP (CentOS 7.2)
- Gobject编程实现
- 美化搜索结果的拼装测试
- 【ProgrammingMicrosoftAzureServiceFabric】第一章:Hello, Service Fabric
- java 基础知识
- RecyclerView的自定义万能分割线
- 开发小记
- 打印机出现命令出错的解决方案
- java 变量
- ACM常用算法