GObject对象系统

Gstreamer基础之Gobject 文章目录Gobject简介 GStreamer是依附于GLib 2.0对象模型的,采用了信号与对象属性的机制,所有的GStreamer对象都采用GObject继承的方法进行扩展,是所有GStreamer对象的基类,因此有必要学习一下Gobject是怎么回事。 Gobject简介 ... 阅读详情
GObject对象系统
简单的说,GObject对象系统是一个建立在GLIB基础上的,
用C语言完成的,具有跨平台特色的、灵活的、可扩展的、非常容易映射到其它语言的面向对象的框架。
如果你是一个C语言的执着的追随者,你没有理由不研究一下它。

NOTE:
glib库是Linux平台下最常用的C语言函数库,它具有很好的可移植性和实用性。
glib是Gtk +库和Gnome的基础。
glib可以在多个平台下使用,比如Linux、Unix、Windows等。glib为许多标准的、常用的C语言结构提供了相应的替代物。
中文名    glib
简    介  Linux平台下最常用的C语言函数库
特    点  很好的可移植性和实用性
类型定义  整数类型

glib库是Linux平台下最常用的C语言函数库,它具有很好的可移植性和实用性。
glib是Gtk+库和Gnome的基础。glib可以在多个平台下使用,比如Linux、Unix、Windows等。
glib为许多标准的、常用的C语言结构提供了相应的替代物。
如果在程序中要使用到glib库中的函数,则应该包含glib.h头文件(在gtk.h和gnome.h头文件中已经包含了glib.h了)

一、前言

大多数现代的计算机语言都带有自己的类型和对象系统,并附带算法结构。
正象GLib提供的基本类型和算法结构(如链表、哈希表等)一样,
GObject的对象系统提供了一种灵活的、可扩展的、并容易映射(到其它语言)的面向对象的C语言框架。
它的实质可以概括为:
 . 一个通用类型系统,用来注册任意的、轻便的、单根继承的、并能推导出任意深度的结构类型的界面,
   它照顾组合对象的定制、初始化和内存管理,类结构,保持对象的父子关系,处理这些类型的动态实现。
   也就是说,这些类型的实现是在运行时重置和卸载的;
 . 一个基本类型的实现集,如整型,枚举型和结构型等;
 . 一个基本对象体系之上的基本对象类型的实现的例子--GObject基本类型;
 . 一个信号系统,允许用户非常灵活的自定义虚的或重载对象的方法,并且能充当非常有效力的通知机制;
 . 一个可扩展的参数/变量体系,支持所有的能被用作处理对象属性或其它参数化类型的基本的类型。

二、类型(GType)与对象(GObject)

GLib中最有特色的是它的对象系统--GObject System,它是以Gtype为基础而实现的一套单根继承的C语言的面向对象的框架。
GType 是GLib 运行时类型认证和管理系统。GType API 是GObject的基础系统,所以理解GType是理解GObject的关键。
Gtype提供了注册和管理所有基本数据类型、用户定义对象和界面类型的技术实现。
(注意:在运用任一GType和GObject函数之前必需运行g_type_init()函数来初始化类型系统。)
为实现类型定制和注册这一目的,所有类型必需是静态的或动态的这二者之一。
静态的类型永远不能在运行时加载或卸载,而动态的类型则可以。
静态类型由g_type_register_static()创建,通过GTypeInfo结构来取得类型的特殊信息。
动态类型则由g_type_register_dynamic()创建,用GTypePlugin结构来取代GTypeInfo,并且还包括g_type_plugin_*()系列API。
这些注册函数通常只运行一次,目的是取得它们返回的专有类的类型标识。
还可以用g_type_register_fundamental来注册基础类型,它同时需要GTypeInfo和GTypeFundamentalInfo两个结构,
事实上大多数情况下这是不必要的,因为系统预先定义的基础类型是优于用户自定义的。
(本文重点介绍创建和使用静态的类型。)

三、对象的定义

在GObject系统中,对象由三个部分组成:
 . 对象的ID标识(唯一,无符号长整型,所有此类对象共同的标识);
 . 对象的类结构(唯一,结构型,由对象的所有实例共同拥有);
 . 对象的实例(多个,结构型,对象的具体实现)。
基于GObject的对象到底是什么样的呢?下面是基于GObject的简单对象 -- Boy的定义代码:
/* boy.h */
#ifndef __BOY_H__
#define __BOY_H__
#include <glib-object.h>
#define BOY_TYPE (boy_get_type())
#define BOY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),BOY_TYPE,Boy))

typedef struct _Boy Boy;
typedef struct _BoyClass BoyClass;
struct _Boy {
  GObject parent;
  //
  gint age;
  gchar *name;
  void (*cry)(void);
};
struct _BoyClass {
  GObjectClass parent_class;
  //
  void (*boy_born)(void);
};
GType boy_get_type(void);
Boy*  boy_new(void);
int boy_get_age(Boy *boy);
void boy_set_age(Boy *boy, int age);
char* boy_get_name(Boy *boy);
void boy_set_name(Boy *boy, char *name);
Boy*  boy_new_with_name(gchar *name);
Boy*  boy_new_with_age(gint age);
Boy*  boy_new_with_name_and_age(gchar *name, gint age);
void  boy_info(Boy *boy);
#endif /* __BOY_H__*/
​
这是一段典型的C语言头文件定义,包括编译预处理,宏定义,数据结构定义和函数声明;
首先要看的是两个数据结构对象Boy和BoyClass,
结构类型_Boy是Boy对象的实例,就是说我们每创建一个Boy对象,也就同时创建了一个Boy结构。
Boy对象中的parent表示此对象的父类,GObject系统中所有对象的共同的根都是GObject类,所以这是必须的;
其它的成员可以是公共的,这里包括表示年龄的age,表示名字的name和表示方法的函数指针cry,外部代码可以操作或引用它们。
结构类型_BoyClass是Boy对象的类结构,它是所有Boy对象实例所共有的。
BoyClass中的parent_class是GObjectClass,同GObject是所有对象的共有的根一样,GObejctClass是所有对象的类结构的根。
在BoyClass中我们还定义了一个函数指针boy_born,也就是说这一函数指针也是所有Boy对象实例共有的,
所有的Boy实例都可以调用它;同样,如果需要的话,你也可以在类结构中定义其它数据成员。
其余的函数定义包括三种,
一种是取得Boy对象的类型ID的函数boy_get_type,这是必须有的;
另一种是创建Boy对象实例的函数boy_new和boy_new_with_*,这是非常清晰明了的创建对象的方式,
当然你也可以用g_object_new函数来创建对象;
第三种是设定或取得Boy对象属性成员的值的函数boy_get_*和boy_set_*。
正常情况下这三种函数都是一个对象所必需的,另外一个函数boy_info用来显示此对象的当前状态。
宏在GObject系统中用得相当广泛,也相当重要,这里我们定义了两个非常关键的宏,
BOY_TYPE宏封装了boy_get_type函数,可以直接取得并替代Boy对象的ID标识;
BOY(obj)宏是G_TYPE_CHECK_INSTANCE_CAST宏的再一次封装,
目的是将一个Gobject对象强制转换为Boy对象,这在对象的继承中十分关键,也经常用到。

四、对象的实现

下面的代码实现了上面的Boy对象的定义:
/* boy.c */
#include "boy.h"
enum { BOY_BORN, LAST_SIGNAL };
static gint boy_signals[LAST_SIGNAL] = { 0 };
static void boy_cry (void);
static void boy_born(void);
static void boy_init(Boy *boy);
static void boy_class_init(BoyClass *boyclass);
GType boy_get_type(void)
{
  static GType boy_type = 0;
  if(!boy_type)
  {
    ​static const GTypeInfo boy_info = {
      ​​sizeof(BoyClass),
      ​​NULL,NULL,
     ​ ​(GClassInitFunc)boy_class_init,​NULL,NULL,
     ​ ​sizeof(Boy),
  ​    ​0,
    ​  ​(GInstanceInitFunc)boy_init
  ​  };
    ​boy_type = g_type_register_static(G_TYPE_OBJECT,"Boy",&boy_info,0);
  }
  return boy_type;
}
static void boy_init(Boy *boy)
{
  boy->age = 0;
  boy->name = "none";
  boy->cry = boy_cry;
}
static void boy_class_init(BoyClass *boyclass)
{
  boyclass->boy_born = boy_born;
  boy_signals[BOY_BORN] = g_signal_new("boy_born",
  BOY_TYPE,
  G_SIGNAL_RUN_FIRST,
  G_STRUCT_OFFSET(BoyClass,boy_born),
  NULL,NULL,
  g_cclosure_marshal_VOID__VOID,
  G_TYPE_NONE, 0, NULL);
}
Boy *boy_new(void)
{
  Boy *boy;
  boy = g_object_new(BOY_TYPE, NULL);
  g_signal_emit(boy,boy_signals[BOY_BORN],0);
  return boy;
}
int boy_get_age(Boy *boy)
{
  return boy->age;
}
void boy_set_age(Boy *boy, int age)
{
boy->age = age;
}
char *boy_get_name(Boy *boy)
{
  return boy->name;
}
void boy_set_name(Boy *boy, char *name)
{
  boy->name = name;
}
Boy*  boy_new_with_name(gchar *name)
{
  Boy* boy;
  boy = boy_new();
  boy_set_name(boy, name);
  return boy;
}
Boy*  boy_new_with_age(gint age)
{
  Boy* boy;
  boy = boy_new();
  boy_set_age(boy, age);
  return boy;
}
Boy *boy_new_with_name_and_age(gchar *name, gint age)
{
  Boy *boy;
  boy = boy_new();
  boy_set_name(boy,name);
  boy_set_age(boy,age);
  return boy;
}
static void boy_cry (void)
{
  g_print("The Boy is crying ......\n");
}
static void boy_born(void)
{
  g_print("Message : A boy was born .\n");
}
​void  boy_info(Boy *boy)
{
  g_print("The Boy name is %s\n", boy->name);
  g_print("The Boy age is %d\n", boy->age);
}
在这段代码中,出现了实现Boy对象的关键函数,这是在Boy对象的定义中未出现的,也是没必要出现的。
就是两个初始化函数,boy_init和boy_class_init,它们分别用来初始化实例结构和类结构。
它们并不被在代码中明显调用,关键是将其用宏转换为地址指针,然后赋值到GTypeInfo结构中,
然后由GType系统自行处理,同时将它们定义为静态的也是非常必要的。
GTypeInfo结构中定义了对象的类型信息,包括以下内容:
包括类结构的长度(必需,即我们定义的BoyClass结构的长度);
基础初始化函数(base initialization function,可选);
基础结束化函数(base finalization function,可选); 
(以上两个函数可以对对象使用的内存来做分配和释放操作,使用时要用GBaseInitFunc和GBaseFinalizeFunc来转换为指针,
本例中均未用到,故设为NULL。)
类初始化函数(即我们这里的boy_class_init函数,用GclassInit宏来转换,可选,仅用于类和实例类型);
类结束函数(可选);
实例初始化函数(可选,即我们这里的boy_init函数);
最后一个成员是GType变量表(可选)。
定义好GTypeInfo结构后就可以用g_type_register_static函数来注册对象的类型了。
g_type_register_static函数用来注册对象的类型,它的第一个参数是表示此对象的父类的对象类型
,我们这里是G_TYPE_OBJECT,这个宏用来表示GObject的父类;
第二个参数表示此对象的名称,这里为"Boy";
第三个参数是此对象的GTypeInfo结构型指针,这里赋值为&boyinfo;
第四个参数是对象注册成功后返回此对象的整型ID标识。
g_object_new函数,用来创建一个基于G_OBJECT的对象,它可以有多个参数,
第一个参数是上面说到的已注册的对象标识ID;
第二个参数表示后面参数的数量,如果为0,则没有第三个参数;
第三个参数开始类型都是GParameter类型,它也是一个结构型,
定义为:
struct GParameter{
const gchar* name;
GValue value;
};
关于GValue,它是变量类型的统一定义,它是基础的变量容器结构,用于封装变量的值和变量的类型,可以GOBJECT文档的GVALUE部分。

五、信号的定义和应用

在GObject系统中,信号是一种定制对象行为的手段,同时也是一种多种用途的通知机制。
初学者可能是在GTK+中首先接触到信号这一概念的,事实上在普通的字符界面编程中也可以正常应用,这可能是很多初学者未曾想到的。
一个对象可以没有信号,也可以有多个信号。
当有一或多个信号时,信号的名称定义是必不可少的,此时C语言的枚举类型的功能就凸显出来了,
用LAST_SIGNAL来表示最后一个信号(不用实现的信号)是一种非常良好的编程风格。
这里为Boy对象定义了一个信号BOY_BORN,在对象创建时发出,表示Boy对象诞生。
同时还需要定义静态的整型指针数组来保存信号的标识,以便于下一步处理信号时使用。
对象的类结构是所有对象的实例所共有的,我们将信号也定义在对象的类结构中,
如此信号同样也是所有对象的实例所共有的,任意一个对象的实例都可以处理信号。
因此我们有必要在在类初始化函数中创建信号(这也可能是GObject设计者的初衷)。
函数g_signal_new用来创建一个新的信号,它的详细使用方法可以在GObject的API文档中找到。
信号创建成功后,返回一个信号的标识ID,如此就可以用发射信号函数g_signal_emit向指定义对象的实例发射信号,
从而执行相应的功能。
本例中每创建一个新的Boy对象,就会发射一次BOY_BORN信号,也就会执行一次我们定义的boy_born函数,
也就输出一行"Message : A boy was born ."信息。

六、对象的属性和方法

对象实例所有的属性和方法一般都定义在对象的实例结构中,属性定义为变量或变量指针,
而方法则定义为函数指针,如此,我们一定要定义函数为static类型,当为函数指针赋值时,才能有效。

七、对象的继承

以下为继承自Boy对象的Man对象的实现,Man对象在Boy对象的基础上又增加了一个属性job和一个方法bye。
#ifndef __MAN_H__
#define __MAN_H__
#include "boy.h"
#define MAN_TYPE  (man_get_type())
#define MAN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MAN_TYPE,Man))
typedef struct _Man Man;
typedef struct _ManClass ManClass;
struct _Man {
  Boy parent;
  char *job;
  void (*bye)(void);
};
struct _ManClass {
  BoyClass parent_class;
};
GType man_get_type(void);
Man*  man_new(void);
gchar* man_get_gob(Man *man);
void  man_set_job(Man *man, gchar *job);
Man*  man_new_with_name_age_and_job(gchar *name, gint age, gchar *job);
void man_info(Man *man);
#endif //__MAN_H__

/* man.c */
#include "man.h"
static void man_bye(void);
static void man_init(Man *man);
static void man_class_init(Man *man);
GType man_get_type(void)
{
static GType man_type = 0;
if(!man_type)
{
static const GTypeInfo man_info = {
sizeof(ManClass),
NULL, NULL,
(GClassInitFunc)man_class_init,
NULL, NULL,
sizeof(Man),
0,
(GInstanceInitFunc)man_init
};
man_type = g_type_register_static(BOY_TYPE, "Man", &man_info, 0);
}
return man_type;
}
static void man_init(Man *man)
{
man->job = "none";
man->bye = man_bye;
}
static void man_class_init(Man *man)
{
}
Man*  man_new(void)
{
Man *man;
man = g_object_new(MAN_TYPE, 0);
return man;
}
gchar* man_get_gob(Man *man)
{
return man->job;
}
void  man_set_job(Man *man, gchar *job)
{
man->job = job;
}
Man*  man_new_with_name_age_and_job(gchar *name, gint age, gchar *job)
{
Man *man;
man = man_new();
boy_set_name(BOY(man), name);
boy_set_age(BOY(man), age);
man_set_job(man, job);
return man;
}
static void man_bye(void)
{
g_print("Goodbye everyone !\n");
}
void man_info(Man *man)
{
g_print("the man name is %s\n", BOY(man)->name);
g_print("the man age is %d\n", BOY(man)->age);
g_print("the man job is %s\n", man->job);
}
关键在于定义对象时将父对象实例定义为Boy,父类设定为BoyClass,
在注册此对象时将其父对象类型设为BOY_TYPE,在设定对象属性时如用到父对象的属性要强制转换下,
如取得对象的name属性,就必须用BOY(obj)->name,因为Man本身没有name属性,而其父对象Boy有,
所以用BOY宏将其强制为Boy类型的对象。

八、测试我们定义的对象

#include <glib.h>
#include "boy.h"
#include "man.h"
int main(int argc, char *argv[])
{
Boy *tom, *peter;
Man *green, *brown; 
g_type_init();//注意,初始化类型系统,必需
tom = boy_new_with_name("Tom");
tom->cry();
boy_info(tom);
peter = boy_new_with_name_and_age("Peter", 10);
peter->cry();
boy_info(peter);
green = man_new();
boy_set_name(BOY(green), "Green");
//设定Man对象的name属性用到其父对象Boy的方法
boy_set_age(BOY(green), 28);
man_set_job(green, "Doctor");
green->bye();
man_info(green);
brown = man_new_with_name_age_and_job("Brown", 30, "Teacher");
brown->bye();
man_info(brown);
}
Makefile文件如下:
CC = gcc
all:
$(CC) -c boy.c `pkg-config --cflags glib-2.0 gobject-2.0`
$(CC) -c man.c `pkg-config --cflags glib-2.0 gobject-2.0`
$(CC) -c main.c `pkg-config --cflags glib-2.0 gobject-2.0`
$(CC) -o simple boy.o man.o main.o `pkg-config --libs glib-2.0 gobject-2.0`
执行make命令编译,编译结束后,执行./simple运行此测试程序,输出结果如下:
Message : A boy was born .
The Boy is crying ......
The Boy name is Tom
The Boy age is 0
Message : A boy was born .
The Boy is crying ......
The Boy name is Peter
The Boy age is 10
Goodbye everyone !
the man name is Green
the man age is 28
the man job is Doctor
Goodbye everyone !
the man name is Brown
the man age is 30
the man job is Teacher
Makefile中用到`pkg-config -cflags -libs gobject-2.0`,
在GLIB中将线程(gthread),插件(gmoudle)和对象系统(gobject)这三个子系统区别对待,编译时要注意加入相应的参数。
本文只是概要的介绍了如何定义和实现GObject对象,GObject系统中还有很多相关内容,
如:枚举和标识类型(Enumeration and flags types);
Gboxed,是Gtype系统中注册一种封装为不透明的C语言结构类型的机制;
许多对象用到的参数对象都是C结构类型,使用者不必了解其结构的内部定义,即不透明,GBoxed即是实现这一功能的机制;
标准的参数和变量类型的定义(Standard Parameter and Value Types)等,它们都以C语言来开发,是深入了解和掌握GObject的关键。
透过以上代码实现,我们还可以看出,以GLIB为基础的GTK+/GNOME开发环境所具有的独特的编程风格和独到的开发思想。
这一点在长期的编程实践中会体验得更深刻。
有了GObject系统这一基础,GTK+通过它将X窗口环境中的控件(Widget)巧妙的封装起来,
这使开发LINUX平台上的GUI应用程序更方便,更快捷。
以上代码在Redhat 8.0 Linux平台,GLIB2.2.1环境下编译通过。
GLib GObject对象系统 在前面的文章中,我们学习了GTK4的自定义控件开发。通过继承GtkWidget,可以创建功能完整的自定义控件。但自定义控件背后的机制是什么?GTK4的控件系统如何实现类型安全、信号通信和属性管理?答案就是GObject。GObject是GTK的对象系统基础面向对象:在C语言中实现类、继承、接口类型系统:动态类型注册和查询信号机制:观察者模式的完整实现属性系统:自动化的getter/setter和通知机制// 枚举属性IDenum {PROP_NAME,N_PROPS// 安装属性。 阅读详情

相关推荐

Livox MID360与Fast-LIO2的实战部署指南:从驱动安装到点云处理

本文提供Livox MID360激光雷达与Fast-LIO2激光惯性里程计从零开始的实战部署指南。详细介绍了Ubuntu系统下的驱动安装、网络配置、点云数据验证以及Fast-LIO2算法的编译、参数配置与联合启动流程,帮助开发者快速搭建移动机器人SLAM系统,并包含关键参数调优与常见故障排查方法。

java5的博客 1024

6. Gobject 学习总结

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

吾皇的博客 4778

实测对比:DeepSeek、豆包、千问三大AI模型生成测试用例谁更强?(附完整代码)

本文通过实测对比了DeepSeek、豆包、千问三大AI模型在生成测试用例方面的表现。文章提供了完整的Python代码实现,详细分析了各模型在用例完整性、准确性、边界覆盖及幻觉控制等维度的差异,并分享了工程化集成与多模型融合等优化策略,旨在帮助测试团队选择合适工具以提升工作效率。

ik6789012的博客 943

GObject官方详细文档

目录 背景 数据类型和编程 导出C API GLib动态类型系统 复制功能 约定 不可实例化的基本类型 (如gchar) 可实例化的类型:对象 初始化和销毁 不可实例化的类型:接口 接口初始化 接口销毁 GObject基类 对象实例化 对象内存管理 引用计数 弱引用 引用计数和周期 对象属性 一次访问多个属性 GObject消息传递系统 关闭 C闭包 ...

Ysu_LiuYang的博客 7098

使用 Ansys Q3D 进行电容提取

精确的电容提取在高速和 RF 设计中至关重要。在本博客中,我们演示了如何使用Ansys Q3D Extractor来计算电容值,从基本的平行板电容器开始,然后转到MEMS芯片的切口,以检查焊盘和RF线对整体电容的影响。在下面的比较中,我们使用 Q3D 从 MEMS 芯片切口中提取两种配置的电容矩阵:一种仅带有焊盘,另一种带有连接到 RF 线路的焊盘。这种比较表明,焊盘是总电容的主要贡献者,而 RF 线路则略有增加。按照上述工作流程,提取焊盘的电容,得到的电容矩阵如下所示。,选择一个已识别的网络,然后单击。

jkh920184196的博客 1814

服务器安全配置:二、本地安全策略设置

密码最长使⽤期限”设置为“90天”;“⽤可以还原的加密来存储密码”设置为“禁⽤”“复位账户锁定计数器”设置为15分钟,贴图这里是我自己设置的时间,15分钟也够用,具体看自己需要。”网络访问: 不允许 SAM 帐户和共享的匿名枚举“设置为“已启用””网络访问: 限制对命名管道和共享的匿名访问“设置为“已启用””网络访问: 不允许匿名枚举 SAM 帐户“设置为“已启用”“关机: 允许系统在未登录的情况下关闭”设置为“已禁用”(1)交互式登录:不显示最后的⽤户名”设置为“已启⽤”

weixin_48825672的博客 3135

GObject 简明教程(一)

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

记录学习的过程 2297

金融波动预测:GARCH模型实战解析与ARIMA对比

本文深入解析GARCH模型在金融波动预测中的实战应用,并与传统ARIMA模型进行对比。通过沪深300指数日收益率数据的案例分析,展示GARCH模型如何有效捕捉波动聚集效应,提升极端波动预测准确率。文章包含Python代码实现、参数解读及模型选择指南,为量化交易者提供实用的波动率建模解决方案。

weixin_29098367的博客 189

linux - gobject使用

gobject简介sample*.h*.c 简介 Gobject 系统提供了一个灵活的、可扩展的、并且容易映射到其他语言的面向对象的 C 语言框架. (1)是Glib库的动态类型系统实现,它实现了:   [1] 基于引用计数的内存管理   [2] 实例的构造和析构   [3] 通用的set/get的属性获取方法   [4] 简单易用的信号机制 GObject 的动态类型系统允许程序在运行时进行类型注册,主要目的有两个: (1)使用面向对象的设计方法来编程,GObject 仅依赖于 GLib 和 li

qq_25439881的博客 1631

Siemens SIMATIC软件二次开发:使用C#进行SIMATIC软件二次开发

通过使用OPC-UA通信协议和S7通信库,可以有效地在C#应用程序中与Siemens SIMATIC软件进行数据交换。OPC-UA提供了一个标准化的平台,而S7通信库则提供了直接访问PLC数据的能力。掌握这两种通信方式,将极大地增强在工业自动化领域的二次开发能力。在Siemens SIMATIC软件中,自定义功能块开发是实现二次开发的关键步骤之一。通过C#,可以创建高度定制化的功能块,以满足特定的控制需求。下面,我们将通过一个示例来展示如何使用C#开发一个自定义功能块。OPC-UA通信。

kkchenjj的博客 1414

Android 车载开发深度解析:CarPropertyManager 核心机制与实践指南

摘要: Android Automotive OS中,CarPropertyManager作为车载信息娱乐系统的核心组件,连接应用层与车辆硬件(如车速、油量等),其架构基于分层设计(App→CarAPI→VHAL→ECU),采用发布-订阅模式实现高效数据通信。通过HIDL/AIDL跨进程交互及共享内存优化,延迟可降至2ms以下。安全机制包括分级权限控制(VISIBLE/PROTECTED/SYSTEM_RESTRICTED)和HMAC防篡改。开发时需注意监听器生命周期管理、事件合并降负载及低功耗适配。

郑伟强dev的专栏 344

GObject对象系统(宋国伟老师)

简洁明了,感谢宋国伟老师  看来好几遍了,现在转载以下。 http://www.ibm.com/developerworks/cn/linux/l-gobject/index.html  还有一篇好文章:http://garfileo.is-programmer.com/p

finding的专栏 4333

2026年职业院校技能大赛中职移动应用与开发—数字生活APP原型设计参考答案(含素材)

本模块以产品原型为目标,考查参赛选手熟练收集、分析和归纳客户需求,清晰梳理业务流程,熟练使用UI设计软件进行产品UI/UE设计,掌握正确的UI配色方案,设计出符合业务逻辑的人体工学移动App 原型优秀作品。

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 568

GObject 对象系统

转自:http://blog.youkuaiyun.com/gl_ding/article/details/4520674 链接地址:http://blog.mcuol.com/User/AT91RM9200/Article/9619_1.htm 目的     本文档可用于两个目的:一是作为一篇学习Glib的GObject类型系统的教程,二是用作一篇按步骤使用GObject类型系统的入门

sweet_life的专栏 929

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

上一篇: GStreamer应用开发手册学习笔记之一
下一篇: GStreamer应用开发手册学习笔记之二
北雨南萍
北雨南萍 领域专家: 操作系统技术领域 领域专家: 操作系统技术领域
博客等级 码龄20年 2665粉丝 453原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值