嵌入式全栈开发学习笔记---Linux常用库(json)

news/2024/9/15 22:41:10/ 标签: linux, 单片机, 嵌入式硬件, 数据结构, stm32, json, C/C++

目录

入门级问题

json%3F-toc" style="margin-left:40px;">为什么使用json?

json%3F-toc" style="margin-left:40px;">什么是json?

json-c%E5%BA%93-toc" style="margin-left:0px;">json-c库

json%E6%BA%90%E7%A0%81-toc" style="margin-left:40px;">json源码

安装方法

json-c%20API-toc" style="margin-left:0px;">json-c API

Json类型

C-API

json%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2(json%E5%AF%B9%E8%B1%A1)-toc" style="margin-left:80px;">将一个字符串转换成符合json格式的字符串(json对象)

定义一个字符串数组

json_object%E7%BB%93%E6%9E%84%E4%BD%93%E6%8C%87%E9%92%88-toc" style="margin-left:120px;">定义一个json_object结构体指针

json%E5%AF%B9%E8%B1%A1-toc" style="margin-left:120px;">把一个字符串转换成一个json对象

json%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%9C%B0%E5%9D%80%E7%BB%99%E7%BB%93%E6%9E%84%E4%BD%93%E6%8C%87%E9%92%88-toc" style="margin-left:120px;">将转换成json对象的字符串的地址给结构体指针

json%E6%A0%BC%E5%BC%8F%E7%9A%84json%E5%AF%B9%E8%B1%A1-toc" style="margin-left:80px;">组合json格式的json对象

json%E5%AF%B9%E8%B1%A1-toc" style="margin-left:120px;">第一步,创建空json对象

json%E5%AF%B9%E8%B1%A1%E4%B8%AD%E5%A1%AB%E9%94%AE%E5%80%BC%E5%AF%B9-toc" style="margin-left:120px;">第二步,往空的json对象中填键值对

json%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%AF%B9%E8%B1%A1-toc" style="margin-left:120px;">第三步,将C字符串转换成json字符串格式的对象

json%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%AF%B9%E8%B1%A1-toc" style="margin-left:120px;">第四步,将整数转换成json格式的对象

json%E5%AF%B9%E8%B1%A1-toc" style="margin-left:80px;">解析json对象

json%E5%AF%B9%E8%B1%A1%E8%8E%B7%E5%8F%96%E5%AF%B9%E5%BA%94%E6%95%B0%E6%8D%AE%E7%9A%84json%E5%AF%B9%E8%B1%A1-toc" style="margin-left:120px;">第一步,根据键名,从json对象获取对应数据的json对象

json%E5%AF%B9%E8%B1%A1%E8%BD%AC%E5%8C%96%E4%B8%BA%E5%AF%B9%E5%BA%94%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%95%B0%E6%8D%AE-toc" style="margin-left:120px;">第二步,根据数据类型,将数据对应的json对象转化为对应类型的数据

json%E6%95%B0%E7%BB%84-toc" style="margin-left:80px;">json数组

json%E6%95%B0%E7%BB%84%E5%AF%B9%E8%B1%A1-toc" style="margin-left:120px;">创建json数组对象

往数组里面填充元素

json%E5%AF%B9%E8%B1%A1%E4%B8%AD-toc" style="margin-left:120px;">把数组对象嵌套到json对象中

从对象中把数组对象中每一个元素对象解析出来

json%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93-toc" style="margin-left:0px;">Json-C/S架构json数据传输


目前我们学习完了Linux系统编程和网络编程,现在开始学习linux常用库!

json是一个非常常用的一种库,它跟语言是没有关系的,不仅仅是在C语言里面, 很多语言里面多可以用,它是一种数据包的格式。

入门级问题

json%3F" style="background-color:transparent;margin-left:.0001pt;text-align:left;">为什么使用json?

以QQ注册的场景为例。

当我们注册QQ的时候,我们需要输入很多信息,比如账号,密码还有一些以防之后忘记密码需要找回密码时所需的邮箱账号,或者密保问题等等,这些信息有将放在一个结构体里面,注册成功后,我们登录的时候,就只需要用到账号和密码,那么之前注册的结构体里的其他成员就用不上了,为了节约内存空间只好又重新创建一个登录时用的结构体,这个结构体只放账号和密码,但是这样如果每次一个任务都要重开一个结构体,就太麻烦了。

如果不开新的结构体,之后什么信息都往注册时用的结构体里面添加,这个结构体的体量会变得越来越大,在执行不同的任务时,有可能结构体里面的很多成员是用不上的,这样很浪费资源

json就是为了解决以上这些问题的。Json不像结构体一旦创建,里面的成员就固定了,Json的格式是灵活的。这就是我们在Linux开发里面为什么要使用json的原因,尤其是在CS架构里面,在客户端和服务器进行交互数据的时候,json比结构体更加实用。

json%3F" style="margin-left:.0001pt;text-align:left;">什么是json?

JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。

json其实就是一个键值对

一些合法的Json实例:

{“name”: ”Jack”, ”sex” : ”male”}

{“name”: ”Jack”, ”age” : 18, ”address”: {“country”: “china”, “zip-code”: “10000”}} //json嵌套

{“a”: 1, “b”: [1, 2, 3]}

以上比如name: Jack就是一个json对象,也就是一个键值对,json允许没有“键”,只有“值”,也就是说只有Jack没有name也是可以的。不同的json对象用逗号隔开。一个Json对象内部是用冒号隔开的,json里面嵌套对象用花括号{ }隔开。

json里面无论是字符串还是字符都是用双引号,没有单引号。

json-c%E5%BA%93" style="margin-left:.0001pt;text-align:left;">json-c库

json支持很多种语言

json-c 库中是在嵌入式开发中常用的库。因为很多地方都以json数据数据交互协议, 尤其嵌入式web数据交互时通常会用到json格式, 因此如果需要在产品端进行json数据解析 , json-c 是一个比较不错的选择。

以智能家居的智能开关为例,智能开关和普通的开关相比,它的特别之处在于可以通过手机来控制开/关。手机先把数据发给服务器,服务器再把数据发送到开关上面,开关作为一个嵌入式产品,它要跟服务器不停地进行数据的交互。在嵌入式端我们用到json-c,因为嵌入式端一般都是用C语言来写的,所以需要移植json-c库

json%E6%BA%90%E7%A0%81" style="margin-left:.0001pt;text-align:left;">json源码

链接:https://pan.baidu.com/s/19LJNLTYj--yKWfoYUjt83g

提取码:asn5

安装方法

把上面源码拉到虚拟机上的一个文件夹下,随便一个文件夹都行,路径不指定。然后执行这四句命令就安装成功了。

./autogen.sh

./configure

make

make install

json-c%20API" style="margin-left:.0001pt;text-align:left;">json-c API

Json类型

安装好Json-c之后可以在这个头文件中找到json的类型

支持的对象类型在这个枚举里面

我们常用的就是这个json对象(含有键值对的json对象)

比如这就是一个object类型,

如果只有值,没有键,也可以作为一个json对象,只不过这个json的类型是这个,也就是字符串类型的

还有int,也可以作为json的类型

比如这个json对象的类型就是int,

还有array数组类型

比如

C-API

接下来测试一下将一个字符串转换成符合json格式的json对象

json%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2(json%E5%AF%B9%E8%B1%A1)" style="background-color:transparent;margin-left:.0001pt;text-align:left;">将一个字符串转换成符合json格式的字符串(json对象)

定义一个字符串数组

先定义一个字符串数组

注意,{ }里面的双引号前都要加上转义字符\

json_object%E7%BB%93%E6%9E%84%E4%BD%93%E6%8C%87%E9%92%88" style="background-color:transparent;margin-left:.0001pt;text-align:left;">定义一个json_object结构体指针

然后要定义一个json_object结构体指针

这个结构体的原型可以在json_object_private.h这个头文件中找到

用这个结构体可以表示一个json对象。

json%E5%AF%B9%E8%B1%A1" style="background-color:transparent;margin-left:.0001pt;text-align:left;">把一个字符串转换成一个json对象

把一个字符串转换成一个json对象,我们需要用到这个函数

参数就是要转换成json对象的字符串

json%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%9C%B0%E5%9D%80%E7%BB%99%E7%BB%93%E6%9E%84%E4%BD%93%E6%8C%87%E9%92%88" style="margin-left:.0001pt;text-align:left;">将转换成json对象的字符串的地址给结构体指针

注意我们要包含一个头文件:#include <json-c/json.h>,这个头文件间接包含了其他头文件

编译的时候要加上-ljson-c,因为这个库是我们自己装的,是个外来库。

注意:如果以上编译错误就把头文件#include <json-c/json.h>改成#include <json/json.h>,另外再加上#include <stdlib.h> (int64_t这个类型编译器没有识别。这个类型在stdlib.h头文件里面有定义,所以只要在第一行,#include <stdlib.h>就行,这行代码一定要放在json.h的前面),并且编译的时候加上-ljson

接下来把json对象转换成json格式的字符串输出

用到这个函数:

参数就是Json对象

注意:此时编译运行后如果出现这个错误

就执行这些操作:

先输入命令:find /usr -name "libjson.so.0"

回车后得到一个路径,则复制路径,然后输入:cp 得到的路径   /lib

回车后再编译运行就没问题了

接下来我们来学习自己组合json格式的json对象

json%E6%A0%BC%E5%BC%8F%E7%9A%84json%E5%AF%B9%E8%B1%A1" style="background-color:transparent;margin-left:.0001pt;text-align:left;">组合json格式的json对象

json%E5%AF%B9%E8%B1%A1" style="margin-left:.0001pt;text-align:left;">第一步,创建空json对象

用到这个函数

json%E5%AF%B9%E8%B1%A1%E4%B8%AD%E5%A1%AB%E9%94%AE%E5%80%BC%E5%AF%B9" style="background-color:transparent;margin-left:.0001pt;text-align:left;">第二步,往空的json对象中填键值对

要用到这个函数

这个函数可以在json_oject.h这个头文件里找到详细解释

第一个参数是json对象,第二个参数是“键”,第三个参数是“值”。

json%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%AF%B9%E8%B1%A1" style="margin-left:.0001pt;text-align:left;">第三步,将C字符串转换成json字符串格式的对象

但是我们前面说过一个json对象可以没有键,只有值,所以一个值就是一个json对象,因此第三个参数不是直接填上字符串类型的值就行了,还得把这个值先转换成json对象,此时要用到这个函数:

然后我们继续添加键和值

json%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%AF%B9%E8%B1%A1" style="margin-left:.0001pt;text-align:left;">第四步,将整数转换成json格式的对象

如果值是int类型的数值,我们就需要用到这个函数来讲整型转换成对象

这样我们就完成了键值对的添加

最后可以打印出来看看对不对

编译运行

接下来学习解析,比如客户端通过socket将json对象发给了服务器,服务器收到这个object就要进行解析

json%E5%AF%B9%E8%B1%A1" style="background-color:transparent;margin-left:.0001pt;text-align:left;">解析json对象

我们刚刚添加的这个,里面每一对都是一个json对象

我们解析要做的事情就是把里面每一对都提取出来

比如我们根据”name”从json对象{ "name": "jack", "age": 11, "sex": "male" }中获取”jack”这个json对象,然后再将”jack”这个json对象转换成字符串输出就行了。

json%E5%AF%B9%E8%B1%A1%E8%8E%B7%E5%8F%96%E5%AF%B9%E5%BA%94%E6%95%B0%E6%8D%AE%E7%9A%84json%E5%AF%B9%E8%B1%A1" style="margin-left:.0001pt;text-align:left;">第一步,根据键名,从json对象获取对应数据的json对象

需要用到这个函数:

网上很多人会用这个函数

但是现在都推荐使用这个函数json_object_object_get_ex()

它的第一个参数是从哪个json对象里解析,第二个参数是“键”,第二个参数是存放了解析出来的Json对象的地址的指针的地址(二级指针)

但是由于虚拟机上只有json_object_object_get这个,所以这里我的代码就直接使用了json_object_object_get这个,它的第一个参数是json对象,第二个参数是键,返回值是解析出来的json对象(值)

json%E5%AF%B9%E8%B1%A1%E8%BD%AC%E5%8C%96%E4%B8%BA%E5%AF%B9%E5%BA%94%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%95%B0%E6%8D%AE" style="margin-left:.0001pt;text-align:left;">第二步,根据数据类型,将数据对应的json对象转化为对应类型的数据

要先获取对象类型

获取对象类型需要用到这个函数:

返回值是这个枚举类型:

参数是json对象

然后我们对这个函数的返回值进行判断

如果在已经知道json对象的类型,我们可以不用获取类型和判断了,直接解析和调用对应的函数打印出来就行。

运行结果:

这就是我们解析出来的json对象

接下来学习json数组

json%E6%95%B0%E7%BB%84" style="margin-left:.0001pt;text-align:left;">json数组

json%E6%95%B0%E7%BB%84%E5%AF%B9%E8%B1%A1" style="margin-left:.0001pt;text-align:left;">创建json数组对象

需要用到这个函数

往数组里面填充元素

第一个参数是刚刚创建的数组对象,第二个参数是值(要转换成对象)

json%E5%AF%B9%E8%B1%A1%E4%B8%AD" style="margin-left:.0001pt;text-align:left;">把数组对象嵌套到json对象中

数组在json对象类型中也是一个数组,所以就不需要转换了,直接把数组名(即数组的地址)传给json_object_object_add函数就可以了

运行结果

接下来就从这个obj这个对象中把数组对象中每一个元素对象解析出来

从对象中把数组对象中每一个元素对象解析出来

解析的时候我们需要用到这个函数获取Json数组的长度

参数是一个json对象

json数组对象里面的每一个元素也是一个单独的json对象,我们可以通过下标来获取这些元素对象,要用到这个函数

第一个参数是解析出来的数组对象,第二个参数是要获取的元素对象的下标

运行结果

这就是我们解析出来的数组对象里的每个元素对象

json%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93" style="margin-left:.0001pt;text-align:left;">Json-C/S架构json数据传输

接下来我们来模拟一下客户端向服务器发送json格式的数据的过程

代码演示:

这里我们要用到之前我们写的TCP服务器的代码

在客户端的代码中,在发送数据之前先搞好json对象,然后再发送给服务器

完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>//inet_addr的头文件
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>//close的头文件
#include <stdlib.h>
#include <json/json.h>int main()
{//创建socketint sockfd=socket(PF_INET,SOCK_STREAM,0);if(-1==sockfd){perror("socket");exit(1);}//发送连接请求struct sockaddr_in server_info;//保存服务器的信息bzero(&server_info,sizeof(server_info));server_info.sin_family=PF_INET;server_info.sin_port=htons(7000);server_info.sin_addr.s_addr=inet_addr("192.168.0.163");if(connect(sockfd,(struct sockaddr*)&server_info,sizeof(server_info))==-1){perror("connect");exit(2);}//发送数据//创建json对象struct json_object *json=json_object_new_object();//填充对象json_object_object_add(json,"name",json_object_new_string("jack"));//记得将json格式的字符串转成json格式的对象json_object_object_add(json,"age",json_object_new_int(11));json_object_object_add(json,"sex",json_object_new_string("male"));//发送对象//将json格式的对象转成json格式的字符串类型才能传给sendconst char*buf=json_object_to_json_string(json);if(send(sockfd,buf,strlen(buf),0)==-1)//最后一个参数写成0默认就行{perror("send");}printf("字符串%s发送成功! 长度 %ld \n",buf,strlen(buf));close(sockfd);//关闭socketreturn 0;
}

在服务器端的代码中,当收到客户端的连接请求时,接收客户端的数据,然后解析并打印输出

完整代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <sys/socket.h>//inet_addr的头文件
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>//bzero的头文件
#include <unistd.h>
#include <stdlib.h>
#include <json/json.h>int main()
{//创建socketint sockfd=socket(PF_INET,SOCK_STREAM,0);//地址族:IPV4协议,套接字类型:流式套接字if(-1==sockfd){perror("socket");exit(1);}//绑定信息struct sockaddr_in server_info;//用于保存服务器的信息:IP,PORT,(还有个地址族)bzero(&server_info,sizeof(struct sockaddr_in));//清空server_info.sin_family=PF_INET;//地址族server_info.sin_port=htons(7000);//端口号,大于1024都行,记得转换字节序//server_info.sin_addr.s_addr=inet_addr("127.0.0.1");//这个地址每一台电脑都有回环IP地址用于测试,记得将字符串转换成长整形,并且要记得包含头文件server_info.sin_addr.s_addr=inet_addr("192.168.0.163");//对外通信if(bind(sockfd,(struct sockaddr*)&server_info,sizeof(server_info))==-1)//记得将结构体类型强转一下{perror("bind");exit(2);}//设置监听队列if(listen(sockfd,10)==-1)//队列大小填10用于测试{perror("listen");exit(3);}//程序停在这里监听......printf("等待客户端的连接...\n");//接受连接(阻塞),一旦有客户端向服务器发起连接就调用函数接收struct sockaddr_in client_info;//用于保存客户端的信息int length=sizeof(client_info);int fd=accept(sockfd,(struct sockaddr*)&client_info,(socklen_t *)&length);if(-1==fd){perror("accept");exit(4);}printf("接受客户端的连接 %d\n",fd);//连接后,服务器端要用一个buf接收数据char*buf=(char*)malloc(sizeof(char)*1024);//接受数据放在buf里面,注意,recv里面不能直接写sizeof(buf),这样buf是指针,只有四个字节,我们直接写1024int size=recv(fd,buf,1024,0);//从哪读,读到哪,读多少,属性写成0就行if(size==-1){perror("recv");exit(1);}//从客户端接受过来的是一个json格式的字符串数据,所以要解析//先将json格式的字符串转换成json格式的对象struct json_object*obj=json_tokener_parse(buf);//解析struct json_object*json;json=json_object_object_get(obj,"name");printf("name:%s\n",json_object_get_string(json));json=json_object_object_get(obj,"age");printf("age:%d\n",json_object_get_int(json));json=json_object_object_get(obj,"sex");printf("sex:%s\n",json_object_get_string(json));close(fd);//关闭TCP连接,不能再接收数据close(sockfd);//关闭socket,不能再处理客户端的请求//sockfd用于处理客户端连接 fd用于处理客户端的消息return 0;
}

运行结果:

综上,我们用json格式发送数据比用结构体要好。

下节开始学习libevent!

本篇就到这里,下篇继续!欢迎点击下方订阅本专栏↓↓↓


http://www.ppmy.cn/news/1520176.html

相关文章

代码随想录训练营day51|图论part2

岛屿数量 卡码网题目链接 #include <bits/stdc.h> using namespace std;int dir[4][2] {0,-1,0,1,1,0,-1,0};void dfs(vector<vector<int>> &board, vector<vector<bool>> &visted, int x, int y){for(int i 0; i < 4; i){int nx…

LeetCode131 分割回文串

前言 题目&#xff1a; 131. 分割回文串 文档&#xff1a; 代码随想录——分割回文串 编程语言&#xff1a; C 解题状态&#xff1a; 没搞出来 思路 其实切割问题类似组合问题&#xff0c;但是依旧很困难&#xff0c;知道如何去切割也是一个难点。 代码 class Solution { pr…

ChatGPT 调教教程

ChatGPT 调教教程 目录 引言 ChatGPT 的背景与概述调教的定义与目的 准备工作 硬件与软件要求环境配置数据准备 基础知识 机器学习与深度学习概述Transformer 架构简介预训练与微调 数据收集与处理 数据收集策略数据清洗与预处理数据标注与增强 模型选择与配置 ChatGPT 的…

uniapp vue3安装 uview-plus3+

1.安装依赖 pnpm install uview-plus 注&#xff1a;依赖安装完成后需要重新启动项目才会起作用 2.在main.ts引入uview import { createSSRApp } from "vue"; import App from "./App.vue"; import uViewPlus from uview-plus;export function createA…

Nuxt3入门:资源文件(第2节)

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 Nuxt 为资源存放提供两种选择。可以使用两个目录&#xff08;public/assets&#xff09;来处理样式表、字体或图像等资源。 public/ 此目录中的文件将按原样复制到服务器根目录中。assets/ 此目录中的…

使用定时任务定期删除数据库数据

代码方式 import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceUtils; imp…

堆《数据结构》

堆《数据结构》 1. 堆排序1.1 建堆向上调整建堆向下调整建堆 1.2 利用堆删除思想来进行排序1.3Top-k问题 2.堆的时间复杂度 1. 堆排序 1.1 建堆 建大堆 建小堆 向上调整建堆 AdjustUp建堆 void AdjustUp(HPDataType* a, int child) {// 初始条件// 中间过程// 结束条件int p…

Redis的内存淘汰策略—— volatile-random

volatile-random 策略简介 在 volatile-random 策略下&#xff0c;当 Redis 的内存使用达到配置的上限&#xff08;maxmemory&#xff09;时&#xff0c;它会随机选择一个设置了过期时间的键进行删除&#xff0c;直到释放出足够的内存。这种策略不会考虑键的使用频率或最近访问…

网络安全售前入门08安全服务——Web漏洞扫描服务

目录 1.服务概述 2.服务内容 2.1代码层安全 2.2应用层安全 ​​​​​​​3.服务工具 4.​​​​​​​服务输出 1.服务概述 Web漏洞扫描服务主要针对应用系统漏洞进行扫描,主要包括扫描WEB服务器(IIS、Websphere、Weblogic、Apache等)的漏洞;识别数据库类型;扫描第三…

【原创】edge-tts与基于mpv的edge-playback,使命令行和Python的Text To Speech唾手可得

最近想用Python脚本写一个TTS的小工具。一顿查找下来&#xff0c;发现AI时代手机端上这么普遍的TTS功能&#xff0c;居然在Web上这么稀有。估计都是被云API厂商拿去赚钱了。幸好Edge浏览器还是比较良心地提供了这个功能&#xff0c;不过又是和浏览器紧密结合的。 最终功夫不负…

Zabbix结合Grafana

一、Grafana简介 Grafana 是 Graphite 和 InfluxDB 仪表盘和图形编辑器。Grafana 是开源的&#xff0c;功能齐全的度量仪表盘和图形编辑器&#xff0c;支持 Graphite&#xff0c;InfluxDB 和 OpenTSDB。 Grafana 主要特性&#xff1a;灵活丰富的图形化选项&#xff1b;可以混合…

向沐神学习笔记:GPT,GPT-2,GPT-3 论文精读【论文精读】GPT部分

系列文章目录 例如&#xff1a; 文章目录 系列文章目录一、GPT1、Abstract 二、1、2、3、 三、1、2、3、 四、1、2、3、 五、1、2、3、 六、1、2、3、 七、1、2、3、 八、1、2、3、 一、GPT 同样模型大小&#xff0c;比如一个亿模型大小的时候&#xff0c;bert的性能表现优于…

静态库为什么需要 头文件?编译的时候会编译引用的动/静态库吗?动静态库使用及区别

1、‌静态库‌在编译时直接整合到目标程序中&#xff0c;这意味着静态库中的代码会被完整地复制到最终的可执行文件中。因此&#xff0c;使用静态库编译的程序不依赖于外部库文件&#xff0c;可以在没有安装这些库的机器上独立运行‌。既然如此&#xff0c;为什么还需要头文件&…

【QNX+Android虚拟化方案】104 - MDIO Clause 22、Clause 45 条款介绍

【QNX+Android虚拟化方案】104 - MDIO Clause 22、Clause 45 条款介绍 1. Clause 22 条款通信协议2. Clause 45 条款通信协议3. 通过 Clause 22 访问 Clause 45 的寄存器3.1 读操作时序3.2 写操作时序基于原生纯净代码,自学总结 纯技术分享,不会也不敢涉项目、不泄密、不传播…

单片机原理图与PCB设计心得体会

在电子技术的学习和实践中&#xff0c;单片机原理图与 PCB 设计是至关重要的环节。通过参与相关项目的设计和制作&#xff0c;我深刻体会到了这两个环节的复杂性和挑战性&#xff0c;同时也收获了许多宝贵的经验和知识。本文将详细介绍我在单片机原理图与 PCB 设计过程中的心得…

精准设计与高效开发:用六西格玛设计DFSS实现新能源汽车开发突破

快速变化的市场需求和激烈的竞争迫使制造企业不得不持续创新和优化产品开发流程。如何在保证产品质量的前提下&#xff0c;加快产品开发周期&#xff0c;成为许多企业亟待解决的问题。六西格玛中的DFSS&#xff08;Design for Six Sigma&#xff09;模型提供了一种系统的方法&a…

视频提取字幕的软件有哪些?高效转录用这些

探索视频的奥秘&#xff0c;从字幕开始&#xff01;你是否曾被繁复的字幕处理困扰&#xff0c;渴望有一款简单好用的在线免费软件来轻松解锁字幕提取&#xff1f; 告别手动输入的烦恼&#xff0c;我们为你精选了6款视频字幕提取在线免费软件&#xff0c;它们不仅能一键转录&am…

Kubernetes 网关流量管理:Ingress 与 Gateway API

引言 随着 Kubernetes 在云原生领域的广泛使用&#xff0c;流量管理成为了至关重要的一环。为了有效地管理从外部流入集群的流量&#xff0c;Kubernetes 提供了多种解决方案&#xff0c;其中最常见的是 Ingress 和新兴的 Gateway API。 Ingress 随着微服务架构的发展&#x…

QT教程-十六,QT中如何解析JSON

一&#xff0c;对json的初步认识 &#xff08;这里我们主要说明最常用的&#xff0c;以一个宏观的概念来说一下&#xff09;&#xff0c;json是一种数据格式&#xff0c;作用就是便于传递信息&#xff0c;我们可以按其结构和对应关系&#xff0c;拿到我们想要的数据。其主要结构…

FFmpeg源码:append_packet_chunked、av_get_packet函数分析

AVPacket结构体和其相关的函数分析&#xff1a; FFmpeg存放压缩后的音视频数据的结构体&#xff1a;AVPacket简介 FFmpeg源码&#xff1a;av_init_packet、get_packet_defaults、av_packet_alloc函数分析 FFmpeg源码&#xff1a;av_packet_free_side_data、av_packet_unref、…