Glib之GObject宏介绍
G_DEFINE_TYPE定义一个静态类型
/**
* G_DEFINE_TYPE(`G_DEFINE_TYPE_WITH_CODE`比`G_DEFINE_TYPE`就是多了一个自定义代码参数_C_):
* @TN: 新类型的名字,单词首字母大写,例如:GtkGadget。
* @t_n: 新类型的名字,单词全部小写并且用'_'符号分隔,例如gtk_gadget:
* separated by '_'.
* @T_P: 父类型的#GType,例如:GTK_TYPE_WIDGET
*/
#define G_DEFINE_TYPE(TN, t_n, T_P) G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, {})
/**
* @TN: 新类型的名字,单词首字母大写,例如:GtkGadget。
* @t_n: 新类型的名字,单词全部小写并且用'_'符号分隔,例如gtk_gadget:
* separated by '_'.
* @T_P: 父类型的#GType,例如:GTK_TYPE_WIDGET
* @_f_: 传递给g_type_register_static()函数的参数#GTypeFlags
* @_C_: 插入*_get_type()函数的自定义代码
*
*/
#define G_DEFINE_TYPE_EXTENDED(TN, t_n, T_P, _f_, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, _f_) {_C_;} _G_DEFINE_TYPE_EXTENDED_END()
接下来我们来看下G_DEFINE_TYPE_EXTENDED展开后的代码
_G_DEFINE_TYPE_EXTENDED_BEGIN宏
实现type_name##_get_type函数的前半部
#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \
\
static void type_name##_init (TypeName *self); \
static void type_name##_class_init (TypeName##Class *klass); \
static gpointer type_name##_parent_class = NULL; \
static gint TypeName##_private_offset; \
\
_G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
\
G_GNUC_UNUSED \
static inline gpointer \
type_name##_get_instance_private (TypeName *self) \
{ \
return (G_STRUCT_MEMBER_P (self, TypeName##_private_offset)); \
} \
\
GType \
type_name##_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 (TYPE_PARENT, \
g_intern_static_string (#TypeName), \
sizeof (TypeName##Class), \
(GClassInitFunc) type_name##_class_intern_init, \
sizeof (TypeName), \
(GInstanceInitFunc) type_name##_init, \
(GTypeFlags) flags); \
{ /* custom code follows */
_C_
将自定义代码插入type_name##_get_type函数的中部,自定义代码将被/* custom code follows */和/* following custom code */ 处的{}所包裹
_G_DEFINE_TYPE_EXTENDED_END宏
实现type_name##_get_type函数的后半部
#define _G_DEFINE_TYPE_EXTENDED_END() \
/* following custom code */ \
} \
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
} \
return g_define_type_id__volatile; \
} /* closes type_name##_get_type() */
样例
* |[<!-- language="C" -->
* G_DEFINE_TYPE_EXTENDED (GtkGadget,
* gtk_gadget,
* GTK_TYPE_WIDGET,
* 0,
* G_IMPLEMENT_INTERFACE (TYPE_GIZMO,
* gtk_gadget_gizmo_init));
* ]|
* expands to
* |[<!-- language="C" -->
* static void gtk_gadget_init (GtkGadget *self);
* static void gtk_gadget_class_init (GtkGadgetClass *klass);
* static gpointer gtk_gadget_parent_class = NULL;
* static void gtk_gadget_class_intern_init (gpointer klass)
* {
* gtk_gadget_parent_class = g_type_class_peek_parent (klass);
* gtk_gadget_class_init ((GtkGadgetClass*) klass);
* }
*
* GType
* gtk_gadget_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 (GTK_TYPE_WIDGET,
* g_intern_static_string ("GtkGadget"),
* sizeof (GtkGadgetClass),
* (GClassInitFunc) gtk_gadget_class_intern_init,
* sizeof (GtkGadget),
* (GInstanceInitFunc) gtk_gadget_init,
* 0);
* {
* const GInterfaceInfo g_implement_interface_info = {
* (GInterfaceInitFunc) gtk_gadget_gizmo_init
* };
* g_type_add_interface_static (g_define_type_id, TYPE_GIZMO, &g_implement_interface_info);
* }
* g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
* }
* return g_define_type_id__volatile;
* }
* ]|
* 必须要手动实现的就是实例和类结构的定义,以及实例和类初始化函数的定义
*
* Since: 2.4
*/
Glib之GObject宏介绍的更多相关文章
- 017.Zabbix宏介绍
一 宏介绍 Zabbix宏的作用是便于在模板.Items.Trigger中的引用,名称为{$名称},宏的字符范围为:A~Z/0~9/_. 如:net.tcp.service[ssh,{$SSH_POR ...
- Glib之GObject简介(翻译)
GObject GObject库是Glib库的动态类型系统实现,它实现了: 基于引用计数的内存管理 实例的构造和析构 通用的set/get的属性获取方法 简单易用的信号机制 对象实例化 所述g_obj ...
- GObject调用父类函数
最近在分析Gstreamer的代码时,发现GstPipeline中有如下代码: result = GST_ELEMENT_CLASS (parent_class)->change_state ( ...
- glib实践篇:父类与子类
前言: 众所周知,C语言是一门面向过程的语言,但是不代表就得跟面向对象完全绝缘,在C语言库glib中有gobject那么一套面向对象的机制,基于C语言的面向对象设计便是基于该实现机制. 今天所要实践的 ...
- 迅为iTOP-4418/6818开发板-驱动-IO初始化配置介绍和例程
对于所有的处理器,pad 一般可以分为两大类:IO(输入输出).Power(VDD 和GDD).类似摄像头 IO.以太网 IO.PWM 的 IO 等等,都可以统称为 IO.一个 IO,有可能能够被配置 ...
- zabbix宏(macro)使用:自定义监控阈值
一.简单应用场景 zabbix在监控cpu load时并没有考虑客户端cpu的个数和核心数量,当平均5分钟的负载达到5时zabbix执行报警动作,这样是非常不合理的,笔者的被监控机器有四核和单核,现在 ...
- 嵌入式C语言自我修养 04:Linux 内核第一宏:container_of
4.1 typeof 关键字 ANSI C 定义了 sizeof 关键字,用来获取一个变量或数据类型在内存中所占的存储字节数.GNU C 扩展了一个关键字 typeof,用来获取一个变量或表达式的类型 ...
- C语言基础知识:几种特殊的函数宏封装方式
函数宏介绍 函数宏,即包含多条语句的宏定义,其通常为某一被频繁调用的功能的语句封装,且不想通过函数方式封装来降低额外的弹栈压栈开销. 函数宏本质上为宏,可以直接进行定义,例如: #define INT ...
- VIM辅导:视频教程,文档资料,经典插件
VIM辅导:25个vim视频' 教程 '资源 转自: http://blog.jobbole.com/10250/ 编注:@程序员的那些事 12月14日在新浪微博发起的<你最常用哪些文本编辑 ...
随机推荐
- 实例甜点 Unreal Engine 4迷你教程(2)之用C++改变Image小部件的颜色
完成本迷你教程之前,请前往完成以下迷你教程: ·实例甜点 Unreal Engine 4迷你教程之如何用C++将纹理绘制在UserWidget的Image小部件上: 目标:实现UMG中的此功能: 在上 ...
- 支付宝pc端支付接入PHP实现
引入支付宝接口 放入一个插件库中,方便管理 创建支付类 1.发起支付 public function init() { $order_id = $_REQUEST['order_id']; $orde ...
- UseSubmitBehavior="false" 防止页面重复提交bug
OnClientClick="this.disabled=true;" UseSubmitBehavior="false" 注: 1.当设置UseSubmitB ...
- python中的异常处理机制
python中的异常处理 1.什么是异常 异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止),在python中,错误触发的异 ...
- IDA Pro 权威指南学习笔记(一) - 启动 IDA
启动 IDA 启动 IDA,有一个欢迎界面 之后有一个对话框 选择 New 将启动一个对话框来选择将要分析的文件 选择 Go 将使 IDA 打开一个空白的工作区 如果要选择分析的文件,可以直接拖到 I ...
- 科学家开发新AI系统,可读取大脑信息并表达复杂思想
我们终于找到了一种方法,可以在核磁共振成像的信号中看到这种复杂的想法.美国卡内基梅隆大学的Marcel Just说,思维和大脑活动模式之间的对应关系告诉我们这些想法是如何构建的. 人工智能系统表明,大 ...
- java 高并发解决方案
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
- 06-Location详解之精准匹配
之前nginx不是编译过吗?现在重新make install一下. 刚刚这个是我们新安装的.原始版的nginx,配置文件比较少,便于我们做调试. 试试精准匹配的概念. 匹配的是/.优先匹配这个最精准的 ...
- 【bzoj3940】[Usaco2015 Feb]Censoring
[题目描述] FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S.他有一个包含n个单词的列表,列表里的n个单词 记为t_1...t_N.他希望从S中删除这些单词. FJ每次 ...
- 【bzoj1455】罗马游戏
1455: 罗马游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1061 Solved: 439[Submit][Status][Discuss] ...