GObject学习教程---第十二章:GObject 信号机制——信号注册

Gstreamer基础之Gobject 文章目录Gobject简介 GStreamer是依附于GLib 2.0对象模型的,采用了信号与对象属性的机制,所有的GStreamer对象都采用GObject继承的方法进行扩展,是所有GStreamer对象的基类,因此有必要学习一下Gobject是怎么回事。 Gobject简介 ... 阅读详情

索引:https://blog.youkuaiyun.com/knowledgebao/article/details/84633798

本文是学习学习他人的博客的心得(具体详见“楼主见解”),如果源网站可访问的话,建议直接访问源网站:

楼主见解:

主要讲解信号的流程,不想了解流程,不看也罢。

主要讲解g_signal_new函数的使用,以及具体参数的意义

原型:

guint g_signal_new (const gchar        *signal_name,
                    GType               itype,
                    GSignalFlags        signal_flags,
                    guint               class_offset,
                    GSignalAccumulator  accumulator,
                    gpointer            accu_data,
                    GSignalCMarshaller  c_marshaller,
                    GType               return_type,
                    guint               n_params,
                    ...);

’调用:

  g_signal_new ("hello",
                      G_TYPE_FROM_CLASS (klass),
                      G_SIGNAL_RUN_FIRST,
                      G_STRUCT_OFFSET (SignalDemoClass, default_handler),
                      NULL,
                      NULL,
                      g_cclosure_marshal_VOID__STRING,
                      G_TYPE_NONE,
                      1, 
                      G_TYPE_STRING);

说明:

  • 第 1 个参数是字符串“hello”,它表示信号。
  • 第 2 个参数是 SignalDemo 类的类型 ID,可以使用 G_TYPE_FROM_CLASS 宏从 SignalDemoClass 结构体中获取,也可直接使用 signal-demo.h 中定义的宏 SIGNAL_TYPE_DEMO。
  • 第 3 个参数可暂时略过。
  • 第 4 个参数比较关键,它是一个内存偏移量,主要用于从 SignalDemoClass 结构体中找到 default_handler 指针的位置,可以使用 G_STRUCT_OFFSET 宏来获取,也可以直接根据 signal-demo.h 中的 SignalDemoClass 结构体的定义,使用 sizeof (GObjectClass) 来得到内存偏移量,因为 default_handler 指针之前只有一个 GObjectClass 结构体成员。
  • 第 5 个和第 6 个参数暂时略过。
  • 第 7 个参数设定闭包的  marshal。在文档“函数指针、回调函数与 GObject 闭包” 中,描述了 GObject 的闭包的概念与结构,我们可以将它视为回调函数 + 上下文环境而构成的一种数据结构,或者再简单一点,将其视为回调函数。另外,在那篇文档中,我们也对 marshal 的概念进行了一些粗浅的解释。事实上 marshal 主要是用来“翻译”闭包的参数和返回值类型的,它将翻译的结果传递给闭包。之所以不直接调用闭包,而是在其外加了一层 marshal 的包装,主要是方便 GObject 库与其他语言的绑定。例如,我们可以写一个 pyg_closure_marshal_VOID__STRING 函数,其中可以调用 python 语言编写的“闭包”并将其计算结果传递给 GValue 容器,然后再从 GValue 容器中提取计算结果。
  • 第 8 个参数指定 marshal 函数的返回值类型。由于本例的第 7 个参数所指定的 marshal 是 g_cclosure_marshal_VOID__STRING 函数的返回值是 void,而 void 类型在 GObject 库的类型管理系统是 G_TYPE_NONE 类型。
  • 第 9 个参数指定 g_signal_new 函数向 marshal 函数传递的参数个数,由于本例使用的 marshal 函数是 g_cclosure_marshal_VOID__STRING 函数,g_signal_new 函数只向其传递 1 个参数。
  • 第 10 个参数是可变参数,其数量由第 8 个参数决定,用于指定 g_signal_new 函数向 marshal 函数传递的参数类型。由于本例使用的 marshal 函数是 g_cclosure_marshal_VOID__STRING 函数,并且 g_signal_new 函数只向其传递一个参数,所以传入的参数类型为 G_TYPE_STRING(GObject 库类型管理系统中的字符串类型)。

源博客网址:http://garfileo.is-programmer.com/categories/6934/posts

GObject 信号机制——信号注册

上一篇文档“GObject 的信号机制”只是挖了一个坑便结束了,本篇尝试填坑,不过也不敢有所保证。因为我也不确定会不会因为被 GObject 的信号内幕再次搞晕。

我们先老老实实的阅读 GObject 参考手册的“Concepts / Signal”部分,尽量多获得一些面上的认识。手册中最关键的一句话是:每一个信号在注册的时候都要与某种数据类型(包括 GObject 库中的内建类型或 GObject 子类类型)存在关联,这种数据类型的使用者需要实现信号与闭包的连接,这样在信号被发射时,闭包会被调用。这句话,意味着我们要使用 GObject 信号机制,那么就必须要完成两个步骤:第一个步骤是信号注册,主要解决信号与数据类型的关联问题;第二个步骤是信号连接,主要处理信号与闭包的连接问题。本文主要考察信号注册的大致过程。

信号可以与 GObject 库的类型管理机制中“可实例化”的数据类型进行关联,但是 GObject 参考手册建议我们最好是只在 GObject 子类类型中使用信号,因为信号跟类/对象在逻辑上比较相符。

有 三个函数可以实现信号注册,即 g_signal_newv、g_signal_new_valist 以及 g_signal_new,其中 g_signal_new_valist 与 g_signal_new 函数皆基于 g_signal_newv 函数实现,但是 g_signal_new 函数的名字看上去最平易近人。我们不理睬它们内部是如何实现的,只需要理解它们所接受的参数的含义即可。所以,我们可以从分析 g_signal_new 函数的参数来理解有关信号注册的一些概念。

g_signal_new 函数的声明如下:

1

2

3

4

5

6

7

8

9

10

guint g_signal_new (const gchar        *signal_name,

                    GType               itype,

                    GSignalFlags        signal_flags,

                    guint               class_offset,

                    GSignalAccumulator  accumulator,

                    gpointer            accu_data,

                    GSignalCMarshaller  c_marshaller,

                    GType               return_type,

                    guint               n_params,

                    ...);

g_signal_new 函数的参数较多,其中每个参数多少都有点深不可测的背景,所以直接理解是非常困难的。我们需要构建实例,从而获得最直观的理解。

首先,我们定义一个 GObject 的子类——SignalDemo 类,其头文件 signal-demo.h 内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

#ifndef SIGNAL_DEMO_H

#define SIGNAL_DEMO_H

  

#include <glib-object.h>

  

#define SIGNAL_TYPE_DEMO (signal_demo_get_type ())

#define SIGNAL_DEMO(object) \

        G_TYPE_CHECK_INSTANCE_CAST ((object), SIGNAL_TYPE_DEMO, SignalDemo)

#define SIGNAL_IS_DEMO(object) \

        G_TYPE_CHECK_INSTANCE_TYPE ((object), SIGNAL_TYPE_DEMO))

#define SIGNAL_DEMO_CLASS(klass) \

        (G_TYPE_CHECK_CLASS_CAST ((klass), SIGNAL_TYPE_DEMO, SignalDemoClass))

#define SIGNAL_IS_DEMO_CLASS(klass) \

        (G_TYPE_CHECK_CLASS_TYPE ((klass), SIGNAL_TYPE_DEMO))

#define SIGNAL_DEMO_GET_CLASS(object) (\

                G_TYPE_INSTANCE_GET_CLASS ((object), SIGNAL_TYPE_DEMO, SignalDemoClass))

  

typedef struct _SignalDemo SignalDemo;

struct _SignalDemo {

        GObject parent;

};

  

typedef struct _SignalDemoClass SignalDemoClass;

struct _SignalDemoClass {

        GObjectClass parent_class;

        void (*default_handler) (gpointer instance, const gchar *buffer, gpointer userdata);

};

  

GType signal_demo_get_type (void);

 

#endif

SignalDemo 类的源文件 signal-demo.c 内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include "signal-demo.h"

 

G_DEFINE_TYPE (SignalDemo, signal_demo, G_TYPE_OBJECT);

 

static void

signal_demo_default_handler (gpointer instance, const gchar *buffer, gpointer userdata)

{

        g_printf ("Default handler said: %s\n", buffer);

}

 

void

signal_demo_init (SignalDemo *self)

{

}

 

void

signal_demo_class_init (SignalDemoClass *klass)

{

        klass->default_handler = signal_demo_default_handler;

}

基于此前所写的 GObject 学习笔记系列,上述代码不难理解,无非就是定义了一个 SignalDemo 类,其类结构体中包含了一个函数指针 default_handler,并在类结构体初始化函数中使该指针指向函数 signal_demo_default_handler。

下面我们开始为 SignalDemo 类注册一个“hello”信号,只需修改一下 SignalDemo 类的类结构体初始化函数,即:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

void

signal_demo_class_init (SignalDemoClass *klass)

{

        klass->default_handler = signal_demo_default_handler;

 

        g_signal_new ("hello",

                      G_TYPE_FROM_CLASS (klass),

                      G_SIGNAL_RUN_FIRST,

                      G_STRUCT_OFFSET (SignalDemoClass, default_handler),

                      NULL,

                      NULL,

                      g_cclosure_marshal_VOID__STRING,

                      G_TYPE_NONE,

                      1,

                      G_TYPE_STRING);

}

此时,观察一下 g_signal_new 函数的参数:

  • 第 1 个参数是字符串“hello”,它表示信号。
  • 第 2 个参数是 SignalDemo 类的类型 ID,可以使用 G_TYPE_FROM_CLASS 宏从 SignalDemoClass 结构体中获取,也可直接使用 signal-demo.h 中定义的宏 SIGNAL_TYPE_DEMO。
  • 第 3 个参数可暂时略过。
  • 第 4 个参数比较关键,它是一个内存偏移量,主要用于从 SignalDemoClass 结构体中找到 default_handler 指针的位置,可以使用 G_STRUCT_OFFSET 宏来获取,也可以直接根据 signal-demo.h 中的 SignalDemoClass 结构体的定义,使用 sizeof (GObjectClass) 来得到内存偏移量,因为 default_handler 指针之前只有一个 GObjectClass 结构体成员。
  • 第 5 个和第 6 个参数暂时略过。
  • 第 7 个参数设定闭包的  marshal。在文档“函数指针、回调函数与 GObject 闭包” 中,描述了 GObject 的闭包的概念与结构,我们可以将它视为回调函数 + 上下文环境而构成的一种数据结构,或者再简单一点,将其视为回调函数。另外,在那篇文档中,我们也对 marshal 的概念进行了一些粗浅的解释。事实上 marshal 主要是用来“翻译”闭包的参数和返回值类型的,它将翻译的结果传递给闭包。之所以不直接调用闭包,而是在其外加了一层 marshal 的包装,主要是方便 GObject 库与其他语言的绑定。例如,我们可以写一个 pyg_closure_marshal_VOID__STRING 函数,其中可以调用 python 语言编写的“闭包”并将其计算结果传递给 GValue 容器,然后再从 GValue 容器中提取计算结果。
  • 第 8 个参数指定 marshal 函数的返回值类型。由于本例的第 7 个参数所指定的 marshal 是 g_cclosure_marshal_VOID__STRING 函数的返回值是 void,而 void 类型在 GObject 库的类型管理系统是 G_TYPE_NONE 类型。
  • 第 9 个参数指定 g_signal_new 函数向 marshal 函数传递的参数个数,由于本例使用的 marshal 函数是 g_cclosure_marshal_VOID__STRING 函数,g_signal_new 函数只向其传递 1 个参数。
  • 第 10 个参数是可变参数,其数量由第 8 个参数决定,用于指定 g_signal_new 函数向 marshal 函数传递的参数类型。由于本例使用的 marshal 函数是 g_cclosure_marshal_VOID__STRING 函数,并且 g_signal_new 函数只向其传递一个参数,所以传入的参数类型为 G_TYPE_STRING(GObject 库类型管理系统中的字符串类型)。

注意,在上述的 g_signal_new 函数的第 7 个参数的解释中,我提到了闭包。事实上,g_signal_new 函数并没有闭包类型的参数,但是它在内部的确是构建了一个闭包,而且是通过它的第 4 个参数实现的。因为 g_signal_new 函数在其内部调用了 g_signal_type_cclosure_new 函数,后者所做的工作就是从一个给定的类结构体中通过内存偏移地址获得回调函数指针,然后构建闭包返于 g_signal_new 函数。既然 g_signal_new 函数的内部是需要闭包的,那么它的第 7~10 个参数自然都是为那个闭包做准备的。

需要注意,g_cclosure_marshal_VOID__STRING 所约定的回调函数类型为:

1

void (*callback) (gpointer instance, const gchar *arg1, gpointer user_data)

这表明 g_cclosure_marshal_VOID__STRING 需要使用者向其回调函数传入 3 个参数,其中前两个参数是回调函数的必要参数,而第 3 个参数,即 userdata,是为使用者留的“后门”,使用者可以通过这个参数传入自己所需要的任意数据。由于 GObject 闭包约定了回调函数的第 1 个参数必须是对象本身,所以 g_cclosure_marshal_VOID__STRING 函数实际上要求使用者向其传入 2 个参数,但是在本例中 g_signal_new 只向其传递了 1 个类型为 G_TYPE_STRING 类型的参数,这有些蹊跷。

这 是因为 g_signal_new 函数所构建闭包只是让信号所关联的数据类型能够有一次可以自我表现的机会,即可以在信号被触发的时候,能够自动调用该数据类型的某个方法,例如 SignalDemo 类结构体的 default_handler 指针所指向的函数。也就是说,SignalDemo 类自身是没有必要向闭包传递那个“userdata”参数的,只是信号的使用者有这种需求。这就是 g_signal_new 的参数中只表明它向闭包传递了 1 个 G_TYPE_STRING 类型参数的缘故。

上面讲的有些凌乱。现在总结一下:g_signal_new 函数内部所构建的闭包,它在被调用的时候,肯定是被传入了 3 个参数,它们被信号所关联的闭包分成了以下层次:

  • 第 1 个参数是信号的默认闭包(信号注册阶段出现)和信号使用者提供的闭包(信号连接阶段出现)所必需的,但是这个参数是隐式存在的,由 g_signal_new 暗自向闭包传递。
  • 第 2 个参数是显式的,同时也是信号的默认闭包和信号使用者提供的闭包所必须的,这个参数由信号的发射函数(例如 g_signal_emit_by_name)向闭包传递。
  • 第 3 个参数也是显式的,且只被信号使用者提供的闭包所关注,这个参数由信号的连接函数(例如 g_signal_connect)向闭包传递。

若要真正明白上述内容,我们必须去构建 SignalDemo 类的使用者,即 main.c 源文件,内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

#include "signal-demo.h"

 

static void

my_signal_handler (gpointer *instance, gchar *buffer, gpointer userdata)

{

        g_print ("my_signal_handler said: %s\n", buffer);

        g_print ("my_signal_handler said: %s\n", (gchar *)userdata);

}

 

int

main (void)

{

        g_type_init ();

 

        gchar *userdata = "This is userdata";

        SignalDemo *sd_obj = g_object_new (SIGNAL_TYPE_DEMO, NULL);

 

        /* 信号连接 */

        g_signal_connect (sd_obj, "hello",

                          G_CALLBACK (my_signal_handler),

                          userdata);

 

        /* 发射信号 */

        g_signal_emit_by_name (sd_obj,

                               "hello",

                               "This is the second param",

                               G_TYPE_NONE);

 

        return 0;

}

编译 signal-demo.c 与 main.c:

1

$ gcc signal-demo.c main.c -o test $(pkg-config --cflags --libs gobject-2.0)

程序运行结果如下:

1

2

3

4

$ ./test

Default handler said: This is the second param

my_signal_handler said: This is the second param

my_signal_handler said: This is userdata

结合程序的运行结果,再回顾一下第 1 个实例中的那些乱七八糟的内容,现在应该清晰了许多。

现在,我们再来看一下在第 1 个实例中被我们忽略的 g_signal_new 函数的第  3 个参数,我们将其设为 G_SIGNAL_RUN_FIRST。实际上,这个参数是枚举类型,是信号默认闭包的调用阶段的标识,可以是下面 7 种形式中 1 种,也可以是多种组合。

1

2

3

4

5

6

7

8

9

10

typedef enum

{

  G_SIGNAL_RUN_FIRST = 1 << 0,

  G_SIGNAL_RUN_LAST = 1 << 1,

  G_SIGNAL_RUN_CLEANUP = 1 << 2,

  G_SIGNAL_NO_RECURSE = 1 << 3,

  G_SIGNAL_DETAILED = 1 << 4,

  G_SIGNAL_ACTION = 1 << 5,

  G_SIGNAL_NO_HOOKS = 1 << 6

} GSignalFlags;

这个参数被设为 G_SIGNAL_RUN_FIRST,表示信号的默认闭包要先于信号使用者的闭包被调用,这个观察一下上面的 test 程序的输出结果便可知悉。如果我们将这个参数设为 G_SIGNAL_RUN_LAST,则表示信号的默认闭包要迟于信号使用者的闭包而被调用。对于这个参数的理解暂且到此为止,后面在讲述信号连接的时候 还会再次谈到它。

小结

现在,对信号注册的主要过程已有所了解,但是依 g_signal_new 函数的第 5 个与第 6 个参数,对于它们,我现在还不知道如何为其构建实例,以后再说吧。若你读到此处并且知道它们的用法,还望不吝赐教。

转载时,希望不要链接文中图片,另外请保留本文原始出处:http://garfileo.is-programmer.com

GLib GObject对象系统 在前面的文章中,我们学习了GTK4的自定义控件开发。通过继承GtkWidget,可以创建功能完整的自定义控件。但自定义控件背后的机制是什么?GTK4的控件系统如何实现类型安全、信号通信和属性管理?答案就是GObject。GObject是GTK的对象系统基础面向对象:在C语言中实现类、继承、接口类型系统:动态类型注册和查询信号机制:观察者模式的完整实现属性系统:自动化的getter/setter和通知机制// 枚举属性IDenum {PROP_NAME,N_PROPS// 安装属性。 阅读详情

相关推荐

Gobject之signal

GObject 信号(Gignal)主要用于特定事件与响应者之间的连接,它与操作系统级中的信号没有什么关系。 一般在class_init时,由g_signal_new生成一个新信号句柄并绑定回调函数,也可以使用g_signal_connect连接对象和处理方式(回调函数),由g_signal_emit发出信号触发。 guint g_signal_new (const gcha

lp525110627的博客 4279

sec4-信号

信号提供了对象之间的通信手段。当某些事情发生或完成时,就会发出信号。第一步和第四步是在信号所属的对象上完成的。第三步通常在对象之外完成。信号的处理过程是复杂的,要解释所有的特征需要很长的时间。本节的内容仅限于编写简单信号的最基本内容,不一定准确。如果您需要准确的信息,请参阅GObject API参考。描述信号有四个部分。

Creationyang的博客 933

深入掌握GObject系统:基于GObject参考手册的全面解析与实战

在现代C语言开发中,面向对象的设计模式已成为构建大型、可维护系统的核心手段。然而,C语言本身并不原生支持类与对象机制,因此需要借助运行时系统来模拟这些高级抽象。GObject系统正是为此而生——它不仅实现了完整的类与对象模型,还通过GType类型系统支撑了动态类型注册、继承、接口和信号等关键特性。本章将深入剖析GObject如何在C语言层面实现类与对象的定义,并详细解析GClass与GObject结构体的内存布局、初始化流程以及自定义类的完整实现路径。

weixin_32836713的博客 1020

快速上手Gobject

转自:http://blog.youkuaiyun.com/acs713/article/details/7778051 What is G-object? —很多人被灌输了这样一种概念:要写面向对象程序,那么就需要学习一种面向对象编程语言,例如C++、Java、C#等等,而C语言是用来编写结构化程序的。 —事实上,面向对象只是一种编程思想,不是一种编程语言。换句话说,面向对象是一种游戏

haima1998的专栏 1081

深入理解「二进制掩码」:从原理到实践

二进制掩码本质上是一个二进制数,用于通过位操作(如与、或、非、异或等)选择性地操作目标数据的某些位。掩码的每一位(bit)可以看作一个“开关”,决定是否对目标数据的对应位进行操作。二进制掩码是位操作的灵魂,掌握它不仅能提升代码效率,还能解锁许多高级编程技巧。从基础的位提取到复杂的子集枚举,掩码的应用无处不在。希望本文的讲解和代码示例能帮助你快速上手,并在实际项目中灵活运用。如果你有更多关于掩码的疑问或应用场景,欢迎在评论区留言交流!

m0_73494933的博客 2432

calibre QRC提取寄生参数

typical将上面的文件QCI_flow里面的文件 在Cp 到当前 ,其实应该是某几个文件,但是我给忘记了 就全cp过来了 ,无影响,不过也希望大佬指正。

2202_75711937的博客 1518

对g_signal_new()参数的解释

http://nanjingabcdefg.is-programmer.com/posts/24116.html  红色部分为自己加的注释   在GObject中,如果想给自己写的类加上signal,一般需要在*_class_init函数中使用g_signal_new函数,

finding的专栏 5347

头歌操作系统 课堂练习4.2:页式内存管理 答案 无解析

头歌操作系统 课堂练习4.2:页式内存管理 答案 无解析

kercii的博客 1万+

GObject的对象属性

GObject的对象属性 在glib对象系统中,一般的类都是从Gobject类继承过来的。尽管glib是用C语言开发的,它却几乎支持所有的面向对象的特性。这里不谈glib的面向对象机制,只是说说关于GObject对象属性的一些问题。 在OOP中,对象的属性一般用成员变量来表示。编程高手常常告诫我们,把对象的属性隐藏起来,用成员函数去访问,可以减少与使用者之间的耦合,同时可以提高程序

国产开源 GUI 引擎 AWTK 6077

详细介绍pytorch重要的API

Tensor 是 PyTorch 中最基本的数据结构,提供了多种创建和操作张量的函数。Autograd 提供了自动求导功能,可以跟踪 Tensor 上的操作并计算梯度。损失函数用于衡量模型预测值与真实值之间的差异,提供了多种损失函数。是构建神经网络的基础类,提供了定义网络层和前向传播的方法。提供了 GPU 计算的支持,包括设备管理、内存管理等。提供了一些常用的函数式操作,如激活函数、损失函数等。提供了常用的数据集、模型架构和图像转换工具。提供了数据加载和预处理的工具,包括。

hello! 1223

llama.cpp 参数调优大全(4060 最优配置)

本文针对NVIDIA RTX 4060(8GB显存)显卡,提供了llama.cpp参数调优的实战指南。核心策略是采用小模型(7B/8B)配合Q4_K_M量化,通过合理设置GPU层数(-ngl 28)、上下文长度(-c 2048)和批量大小(-b 512)来平衡性能和显存占用。重点推荐启用flash-attn加速和mlock内存锁定,并给出标准、高性能和保守三种配置方案。调优优先级为:GPU利用率>吞吐量>显存>线程数,同时警示避免常见错误如过大上下文或GPU层数设置。最终推荐4060最佳配置为7B Q4_

刘一说的IT专栏 3402

6. Gobject 学习总结

简单的来说,GObject是一个程序库,它可以帮助我们使用C语言编写面向对象的程序。   很多人被灌输了这样一种概念:要写面向对象程序,那么就需要学习一种面向对象编程语言,例如C++、Java、C# 等等,而 C 语言是用来编写结构化程序的。事实上,面向对象只是一种编程思想,不是一种编程语言。换句话说,面向对象是一种游戏规则,它不是游戏。GObject 告诉我们,使用 C 语言编写程序时,可以

吾皇的博客 4778

UFSV3.1-RPMB实现与测试

UFS RPMB功能验证与测试指南 本文介绍了UFS(通用闪存存储)中RPMB(重放保护内存块)的功能验证与测试方法。主要内容包括: RPMB基础配置: 在Linux系统中查看RPMB设备节点 读取RPMB单元描述符获取配置信息 配置RPMB区域大小(16MB)和使能状态 RPMB特性验证: 获取单次写最大请求(16KB) 测试未编程认证密钥时的读写操作 验证认证密钥编程过程 测试用例: 包含4个测试用例,验证RPMB在不同状态下的行为 提供了详细的命令行操作和预期结果 本文可作为UFS RPMB功能验证。

小码哥的博客 1254

GObject 简明教程(一)

最近,我一直在深入学习 GStreamer(相关教程可以从我主页中看到)。在探索其复杂的设计逻辑时,我意识到需要深入研究 GStreamer 的源码。而因为 GStreamer 是基于 GObject 开发的,掌握 GObject 的基本概念就显得尤为重要。本文整理自,简化了细节,保留了一些关键内容,以便更好地理解。提示:以下是本篇文章正文内容,下面案例可供参考。

记录学习的过程 2297

读懂 403 Forbidden, the request has been blocked by UCON.:它不是浏览器渲染问题,而是后端安全闸门在拦截

摘要 403 Forbidden 错误表明服务器理解请求但拒绝执行,通常与权限或访问控制有关。当错误信息显示 "blocked by UCON" 时,说明请求被 SAP 体系中的统一连接管控框架拦截。UCON 采用白名单机制限制外部调用,通过记录、评估、强制三阶段流程实施管控。常见触发场景包括 HTTP 服务与通信场景配置不一致、白名单未更新等。排查时应通过 DevTools 确认服务器响应,使用 curl 排除浏览器干扰,并比较不同环境的行为差异。解决方案通常涉及调整配置传输顺序或更新

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 239

地平线J6的基础简介

地平线J6M芯片:面向中阶辅助驾驶市场的高性价比芯片

weixin_43084908的博客 4453

GObject 参考手册(12)--信号

  原文地址:http://library.gnome.org/devel/gobject/unstable/signal.html 信号 GObject的信号与标准的UNIX信号无关:它们连接应用程序相关的任一数量监听程序的事件。例如:在GTK+中,每个用户事件(按键或鼠标移动)是从X Server和在一个给出的对象实例的信号发射形式下产生的事件接收到的。每一个信号同能被

wjx_sy的专栏 1999

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

GObject 简明教程(二)

最近,我一直在深入学习 GStreamer(相关教程可以从我主页中看到)。在探索其复杂的设计逻辑时,我意识到需要深入研究 GStreamer 的源码。而因为 GStreamer 是基于 GObject 开发的,掌握 GObject 的基本概念就显得尤为重要。本文整理自,简化了细节,保留了一些关键内容,以便更好地理解。上一章GObject 简明教程(一)我们介绍了的前面五章。今天我们继续,将后面几章也进行总结和更新。

记录学习的过程 959

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

GObject学习教程---第十章:GObject 的信号机制——概览

索引:https://blog.youkuaiyun.com/knowledgebao/article/details/84633798 本文是学习学习他人的博客的心得(具体详见“楼主见解”),如果源网站可访问的话,建议直接访问源网站: 楼主见解: 主要讲解信号机制的实现,分下边几步 第一:继承GObject,在class的inite函数中,创建一个信号file_changed.函数g_signal_...

knowledgebao的博客 3252

GObject学习教程---第十四章:GObject 信号机制——信号连接

索引:https://blog.youkuaiyun.com/knowledgebao/article/details/84633798 本文是学习学习他人的博客的心得(具体详见“楼主见解”),如果源网站可访问的话,建议直接访问源网站: 楼主见解: 解释g_signal_connect,不读也罢。 源博客网址:http://garfileo.is-programmer.com/categories/6...

knowledgebao的博客 2185

GObject消息系统之Signals

GObject的信号与标准UNIX信号无关:它们将任意特定于应用程序的事件与任意数量的监听者连接起来。 例如,在GTK +中,从窗口系统接收到每个用户事件 (按键或鼠标移动),并在窗口小部件对象实例上以信号发射的形式生成GTK+事件。 每个信号在类型系统中与其可以发射的类型一起注册:当用户注册的信号发射时指定的实例类型的闭合被调用。用户还可以自己发射信号,或者从连接到信号的 闭合件之一内停止

lp525110627的博客 1307

Gobject专栏索引

索引首页:https://blog.youkuaiyun.com/knowledgebao/article/details/84776046 官网API:https://developer.gnome.org/gobject/stable/ gobject相关概念:https://blog.youkuaiyun.com/knowledgebao/article/details/82498187 第一章:GObjec...

knowledgebao的博客 7528

GObject学习教程---第十三章:GObject 信号机制——信号 Accumulator

索引:https://blog.youkuaiyun.com/knowledgebao/article/details/84633798 本文是学习学习他人的博客的心得(具体详见“楼主见解”),如果源网站可访问的话,建议直接访问源网站: 楼主见解: 主要讲解信号g_signal_new的第5/6个参数。暂时没想到用武之地。 guint g_signal_new (const gchar ...

knowledgebao的博客 928

Gobject tutorial 八

如果这是最后一个对对象B的引用,那么A释放对B的引用,会导致unref 函数执行对象B的dispose, 进而导致B对象释放对对象A的引用,如果这也是对对象A的最后一个引用,对象B对对象A的引用的释放会导致第二次执行A的dispose。既然在注册属性过程中,GparamSpec是必须的,那么,就有必要对生成GParamSpec的函数进行说明,我们以上例中的g_param_spec_float为例,看看Glib的说明。对于不同的对象实例,属性值是不同的,因此,属性值是存储在对象的实例中的。

编程是一门艺术 969

GObject 核心原理与 C 语言面向对象实践:从类型系统到信号机制

在 C 语言大型项目开发中,如何优雅地实现面向对象设计一直是工程实践的核心话题。GObject 作为 GNOME 生态的基石,通过类型系统、类结构体与引用计数机制,将继承、封装、多态等概念引入 C 语言,同时保持 ABI 稳定与跨语言绑定能力。它的属性系统与信号机制为对象提供了标准的可观察性接口,使得 GTK 等图形框架得以可靠扩展。理解 GObject 的类型注册、类初始化、信号连接与生命周期管理,不仅有助于掌握 GNOME 开发底层原理,也能为嵌入式或系统级 C 项目提供一套可复用的对象模型范式。本文从

weixin_34354173的博客 523

[pyvips] GLib | GObject | GValue

我准备了一个盒子`GValue value = G_VALUE_INIT`,放了个整数 42`set_int(&value, 42)`,然后交给别人处理。

No Game No Life 1152
上一篇: GObject学习教程---第十一章:GObject 子类对象的析构过程
下一篇: GObject学习教程---第十三章:GObject 信号机制——信号 Accumulator
knowledgebao
博客等级 码龄15年 401粉丝 198原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值