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日在新浪微博发起的<你最常用哪些文本编辑 ...
随机推荐
- sublime text3 自动编译php 适合用于简单的php文件执行
1.将php路径放入环境变量中 2. 点击 sublime_text的“工具”->"编译系统"->"编译新系统" { "cmd" ...
- redis基本操作和在springboot中的使用
本文介绍redis的使用 redis启动步骤 说明 redis自增自减相关操作 redis string set操作 get操作 其他操作 redis hash set操作 get操作 其他操作 re ...
- python 通过ftplib 实现上传下载
#!/usr/bin/python #-*- coding: utf-8 -*- from ftplib import FTP def ftpconnect() ftp_server = 'ftp.p ...
- struct 方法使用
struct _Worker { _Worker() { pWokerbase=NULL; hThread=INVALID_HANDLE_VALUE; pListConn=NULL; } struct ...
- : error C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
打开项目----项目属性---配置属性----C/C++ ----预处理器----预处理定义,添加_CRT_SECURE_NO_WARNINGS
- 升级到Win10 周年更新版
尝试过强制刷更新,但是没用,最近微软才跟我的机器推送周年更新,于是更新. 花费了些时间更新,之前网上有的那些诗句,亲眼看看还是蛮有意思的. 但是更新完了后,explorer 一直出错,有闪退(闪屏)一 ...
- 【原】Coursera—Andrew Ng斯坦福机器学习(0)——课程地址和软件下载
斯坦福大学机器学习 课程信息 机器学习是一门研究在非特定编程条件下让计算机采取行动的学科.最近二十年,机器学习为我们带来了自动驾驶汽车.实用的语音识别.高效的网络搜索,让我们对人类基因的解读能力大大提 ...
- 生成ssl脚本文件
read -p "Enter your domain [www.example.com]: " DOMAIN echo "Create server key...&quo ...
- HtmlHelper扩展
扩展 HtmlHelper类 public static class MyHtmlHelper { //扩展方法 //静态类,静态方法,this关键字 //调用方法<%=Html.MyLabel ...
- c++ 装饰模式(decorate)
装饰模式:动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类 更为灵活.有时我们希望给某个对象而不是整个类添加一些功能.比如有一个手机,允许你为手机添加特性,比如增加挂件.屏幕贴 ...