当前位置: 首页 > news >正文

Linux-C/C++--初探linux应用编程概念

               

        对于大多数首次接触 Linux 应用编程的读者来说,可能对应用编程(也可称为系统编程)这个概念并不 太了解,所以在正式学习 Linux 应用编程之前,笔者有必要向大家介绍这些简单基本的概念,从整体上认识 到应用编程为何物?与驱动编程、裸机编程有何不同? 了解本章所介绍的内容是掌握应用编程的先决条件,所以本章主要内容便是对 Linux 应用编程进行一 个简单地介绍,让读者对此有一个基本的认识。 本章将会讨论如下主题内容。

何为系统调用;

何为库函数;

应用程序的 main()函数;

应用程序开发环境的介绍。

一、系统调用

        系统调用(system call)其实是 Linux 内核提供给应用层的应用编程接口(API),是 Linux 应用层进入 内核的入口。不止 Linux 系统,所有的操作系统都会向应用层提供系统调用,应用程序通过系统调用来使用 操作系统提供的各种服务。

        通过系统调用,Linux 应用程序可以请求内核以自己的名义执行某些事情,譬如打开磁盘中的文件、读 写文件、关闭文件以及控制其它硬件外设。

        通过系统调用 API,应用层可以实现与内核的交互,其关系可通过下图简单描述:

        内核提供了一系列的服务、资源、支持一系列功能,应用程序通过调用系统调用 API 函数来使用内核 提供的服务、资源以及各种各样的功能,如果大家接触过其它操作系统编程,想必对此并不陌生,譬如 Windows 应用编程,操作系统内核一般都会向应用程序提供应用编程接口 API,否则我们将我无法使用操 作系统。

应用编程与裸机编程、驱动编程有什么区别?

在学习应用编程之前,相信大家都有过软件开发经验,譬如 51STM32 等单片机软件开发、以及嵌入 式 Linux 硬件平台下的驱动开发等,51STM32 这类单片机的软件开发通常是裸机程序开发,并不会涉及 到操作系统的概念,那应用编程与裸机编程以及驱动开发有什么区别呢?

        就拿嵌入式 Linux 硬件平台下的软件开发来说,我们大可将编程分为三种,分别为裸机编程、Linux 驱 动编程以及 Linux 应用编程。首先对于裸机编程这个概念来说很好理解,一般把没有操作系统支持的编程环 境称为裸机编程环境,譬如单片机上的编程开发,编写直接在硬件上运行的程序,没有操作系统支持;狭义 上 Linux 驱动编程指的是基于内核驱动框架开发驱动程序,驱动开发工程师通过调用 Linux 内核提供的接口 完成设备驱动的注册,驱动程序负责底层硬件操作相关逻辑,如果学习过 Linux 驱动开发的读者,想必对此 并不陌生;而 Linux 应用编程(系统编程)则指的是基于 Linux 操作系统的应用编程,在应用程序中通过调 用系统调用 API 完成应用程序的功能和逻辑,应用程序运行于操作系统之上。通常在操作系统下有两种不 同的状态:内核态和用户态,应用程序运行在用户态、而内核则运行在内核态。

        关于应用编程这个概念,以上给大家解释得很清楚了,笔者以实现点亮一个 LED 功能为例,给大家简 单地说明三者之间的区别,LED 裸机程序如下所示:

static void led_on(void)
{/* 点亮 LED 硬件操作代码 */
}static void led_off(void)
{/* 熄灭 LED 硬件操作代码 */
}int main(void)
{/* 用户逻辑 */for ( ; ; ) {led_on(); //点亮 LEDdelay(); //延时led_off(); //熄灭 LEDdelay(); //延时}
}

        可以看到在裸机程序当中,LED 硬件操作代码与用户逻辑代码全部都是在同一个源文件(同一个工程) 中实现的,硬件操作代码与用户逻辑代码没有隔离,没有操作系统支持,代码编译之后直接在硬件平台运 行,俗称“裸跑”。我们再来看一个 Linux 系统下的 LED 驱动程序示例代码,如下所示:

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
static void led_on(void)
{/* 点亮 LED 硬件操作代码 */
}static void led_off(void)
{/* 熄灭 LED 硬件操作代码 */
}static int led_open(struct inode *inode, struct file *filp)
{/* 打开设备时需要做的事情 */
}static ssize_t led_write(struct file *filp, const char __user *buf,size_t size, loff_t *offt)
{int flag;/* 获取应用层 write 的数据,存放在 flag 变量 */if (copy_from_user(&flag, buf, size))return -EFAULT;/* 判断用户写入的数据,如果是 0 则熄灭 LED,如果是非 0 则点亮 LED */if (flag)led_on();elseled_off();return 0;
}
static int led_release(struct inode *inode, struct file *filp)
{/* 关闭设备时需要做的事情 */
}static struct file_operations led_fops = {.owner = THIS_MODULE,.open = led_open,.write = led_write,.release = led_release,
};static int led_probe(struct platform_device *pdev)
{/* 驱动加载时需要做的事情 */
}static int led_remove(struct platform_device *pdev)
{/* 驱动卸载时需要做的事情 */
}static const struct of_device_id led_of_match[] = {{.compatible = "alientek,led", },{ /* sentinel */ },
};MODULE_DEVICE_TABLE(of, led_of_match);
static struct platform_driver led_driver = {.driver = {.owner = THIS_MODULE,.name = "led",.of_match_table = led_of_match,},.probe = led_probe,.remove = led_remove,
};
module_platform_driver(led_driver);
MODULE_DESCRIPTION("LED Driver");
MODULE_LICENSE("GPL");

        以上并不是一个完整的 LED 驱动代码,如果没有接触过 Linux 驱动开发的读者,看不懂也没有关系, 并无大碍,此驱动程序使用了最基本的字符设备驱动框架编写而成,非常简单;led_fops 对象中提供了 open、 write、release 方法,当应用程序调用 open 系统调用打开此 LED 设备时会执行到 led_open 函数,当调用 close 系统调用关闭 LED 设备时会执行到 led_release 函数,而调用 write 系统调用时会执行到 led_write 函数,此 驱动程序的设定是当应用层调用 write 写入 0 时熄灭 LEDwrite 写入非 0 时点亮 LED

         驱动程序属于内核的一部分,当操作系统启动的时候会加载驱动程序,可以看到 LED 驱动程序中仅仅 实现了点亮/熄灭 LED 硬件操作相关逻辑代码,应用程序可通过 write 这个系统调用 API 函数控制 LED 亮 灭;接下来我们看看 Linux 系统下的 LED 应用程序示例代码,如下所示:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{int fd;int data;fd = open("/dev/led", O_WRONLY);//打开 LED 设备(假定 LED 的设备文件为/dev/led)if (0 > fd)return -1;for ( ; ; ) {data = 1;write(fd, &data, sizeof(data)); //写 1 点亮 LEDsleep(1); //延时 1 秒data = 0;write(fd, &data, sizeof(data)); //写 0 熄灭 LEDsleep(1); //延时 1 秒}close(fd);return 0;
}

此应用程序也非常简单,仅只需实现用户逻辑代码即可,循环点亮、熄灭 LED,并不需要实现硬件操 作相关,示例代码中调用了 openwriteclose 这三个系统调用 API 接口,open close 分别用于打开/关闭 LED 设备,write 写入数据传给 LED 驱动,传入 0 熄灭 LED,传入非 0 点亮 LED

二、库函数

        前面给大家介绍了系统调用,系统调用是内核直接向应用层提供的应用编程接口,譬如 openwrite、 read、close 等,关于这些系统调用后面会给大家进行详细介绍。编写应用程序除了使用系统调用之外,我们 还可以使用库函数,本小节来聊一聊库函数。

        在Linux环境下,C语言程序的开发通常需要使用各种库函数来简化编程任务。Linux系统为C语言程序提供了丰富的标准库函数,涵盖了输入输出、字符串处理、内存管理、文件操作、时间和日期、数学运算等多个方面。

        以下是一些常用的C语言库函数的介绍:

2.1、标准输入输出库(stdio.h

该库包含了进行输入输出操作的函数。

printf:用于格式化输出。
int printf(const char *format, ...);
scanf:从标准输入读取数据,按照指定的格式。
int scanf(const char *format, ...);

fopen:打开一个文件。

FILE *fopen(const char *filename, const char *mode);

fclose:关闭打开的文件。

int fclose(FILE *stream);

fread:从文件中读取数据。

size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);

fprintf:向文件输出格式化数据。

int fprintf(FILE *stream, const char *format, ...);

2.2、字符串处理库(string.h

该库包含处理字符串和内存的常用函数。
strlen:返回字符串的长度。
size_t strlen(const char *str);

strcpy:将一个字符串复制到另一个字符串。

char *strcpy(char *dest, const char *src);

strcat:将两个字符串连接起来。

char *strcat(char *dest, const char *src);

strcmp:比较两个字符串。

int strcmp(const char *str1, const char *str2);

strtok:分割字符串为多个子字符串。

char *strtok(char *str, const char *delim);

memcpy:从源地址拷贝指定字节到目标地址。

void *memcpy(void *dest, const void *src, size_t n);

memset:将指定值的字节填充到内存块。

void *memset(void *str, int c, size_t n);

2.3、内存管理库(stdlib.h

该库包含了动态内存分配、进程控制等功能的函数。
malloc:分配指定大小的内存块。
void *malloc(size_t size);

calloc:分配内存块并初始化为零

void *calloc(size_t num, size_t size);

free:释放之前分配的内存块。

void free(void *ptr);
realloc:重新调整已分配内存的大小。
void *realloc(void *ptr, size_t new_size);

exit:终止程序并返回指定状态。

void exit(int status);

atoi:将字符串转换为整数。

int atoi(const char *str);

rand:生成随机数。

int rand(void);

srand:设置随机数种子。

void srand(unsigned int seed);

2.4、 数学库(math.h

该库提供了常用的数学函数。
sqrt:计算平方根。
double sqrt(double x);

pow:计算幂。

double pow(double base, double exponent);

sincostan:三角函数。

double sin(double x);
double cos(double x);
double tan(double x);

log:计算自然对数。

double log(double x);

exp:计算e的x次方。

double exp(double x);

ceil:返回大于或等于参数的最小整数。

double ceil(double x);

floor:返回小于或等于参数的最大整数。

double floor(double x);

2.5、 时间和日期库(time.h

该库包含了处理日期和时间的函数。

time:返回当前时间的秒数。

time_t time(time_t *t);

localtime:将时间转换为本地时间。

struct tm *localtime(const time_t *timep);

strftime:格式化日期和时间。

size_t strftime(char *str, size_t max, const char *format, const struct tm *tm);

difftime:计算两个时间点的差异(单位为秒)。

double difftime(time_t end, time_t beginning);

三、标准 C 语言函数库

        在 Linux 系 统 下 , 使 用 的 C 语 言 库 为 GNU C 语 言 函 数 库 ( 也 叫 作 glibc , 其 网 址 为 http://www.gnu.org/software/libc/),作为 Linux 下的标准 C 语言函数库。

进入到 http://www.gnu.org/software/libc/网址,如下所示:

点击上面的 Sources 选项可以查看它的源码实现:

glibc 源码的获取方式很简单,直接直接从 git 仓库下载,也可以通过 ftp 下载,如果大家有兴趣、或者 想要了解某一个库函数它的具体实现,那么就可以获取到它源码来进行分析,好了,这里就不再多说了!

确定 Linux 系统的 glibc 版本

前面提到过了,C 语言库是以动态库文件的形式提供的,通常存放在/lib 目录,它的命名方式通常是 libc.so.6,不过这个是一个软链接文件,它会链接到真正的库文件。 进入到 Ubuntu 系统的/lib 目录下,笔者使用的 Ubuntu 版本为 16.04,在我的/lib 目录下并没有发现 libc.so.6 这个文件,其实是在/lib/x86_64-linux-gnu 目录下,进入到该目录:

可以看到 libc.so.6 链接到了 libc-2.23.so 库文件,2.23 表示的就是这个 glibc 库的版本号为 2.23。除此之 外,我们还可以直接运行该共享库来获取到它的信息,如下所示:

从打印信息可以看到,笔者所使用的 Ubuntu 系统对应的 glibc 版本号为 2.23

四、main函数

        对学习过 C 语言编程的读者来说,譬如单片机编程、Windows 应用编程等,main 函数想必大家再熟悉 不过了,很多编程开发都是以 main 函数作为程序的入口函数,同样在 Linux 应用程序中,main 函数也是作 为应用程序的入口函数存在,main 函数的形参一般会有两种写法,如果执行应用程序无需传参,则可以写 成如下形式:

int main(void)
{/* 代码 */
}

如果在执行应用程序的时候需要向应用程序传递参数,则写法如下:

int main(int argc, char **argv)
{/* 代码 */
}

argc 形参表示传入参数的个数,包括应用程序自身路径和程序名,譬如运行当前目录下的 hello 可执行 文件,并且传入参数,如下所示:

./hello 112233

那么此时参数个数为 2,并且这些参数都是作为字符串的形式传递给 main 函数:

argv[0]等于"./hello"

argv[1]等于"112233"

有传参时 main 函数的写法并不只有这一种,只是这种写法最常用,对于其它的写法,后面学习过程中 如果遇到了再给大家进行讲解,这里暂时先不去管。

五、开发环境

        对于编程开发,大家可能都比较关心开发环境的问题,譬如本书将使用什么 IDE 编写应用程序之类的 问题,本小节将对开发环境的问题进行一个简单介绍。

        在 Linux 操作系统下,也有很多比较好用的 IDE 软件,可以帮助我们更为轻松的进行软件开发,譬如 Eclipse、vscode 等,如果你会使用 Eclipse,可以在 Ubuntu 系统下安装 Eclipse 进行 Linux 应用开发

        小编使用的是VSCode,vscode 是一个代码编辑器,提供了很多好用的插件,譬如语法检测、高亮显示、智能补全等,大家可以根据自己的选择安装插件。

本小节内容到此结束。2025年决定把linux-C/C++相关内容重温分享给大家。欢迎留言评论,感谢!!!

相关文章:

Linux-C/C++--初探linux应用编程概念

对于大多数首次接触 Linux 应用编程的读者来说&#xff0c;可能对应用编程&#xff08;也可称为系统编程&#xff09;这个概念并不 太了解&#xff0c;所以在正式学习 Linux 应用编程之前&#xff0c;笔者有必要向大家介绍这些简单基本的概念&#xff0c;从整体上认识 到应用编…...

用sklearn运行分类模型,选择AUC最高的模型保存模型权重并绘制AUCROC曲线(以逻辑回归、随机森林、梯度提升、MLP为例)

诸神缄默不语-个人CSDN博文目录 文章目录 1. 导入包2. 初始化分类模型3. 训练、测试模型&#xff0c;绘图&#xff0c;保存指标 1. 导入包 from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier, GradientBoostingClass…...

动手学大数据-3社区开源实践

目录 数据库概览&#xff1a; MaxComput&#xff1a; HAWQ&#xff1a; Hologres&#xff1a; TiDB&#xff1a; Spark&#xff1a; ClickHouse&#xff1a; Apache Calcite 概览 Calcite RBO HepPlanner 优化规则&#xff08;Rule&#xff09; 内置有100优化规则 …...

使用Pydantic驾驭大模型

本文介绍Pydantic 库&#xff0c;首先介绍其概念及优势&#xff0c;然后通过基本示例展示如何进行数据验证。后面通过多个示例解释如何在LangChain中通过Pydantic进行数据验证&#xff0c;保证与大模型进行交互过程中数据准确性&#xff0c;并显示清晰的数验证错误信息。 Pydan…...

【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发之常见布局

目录 1 -> 自适应布局 1.1 -> 线性布局 1.1.1 -> 线性布局的排列 1.1.2 -> 自适应拉伸 1.1.3 -> 自适应缩放 1.1.4 -> 定位能力 1.1.5 -> 自适应延伸 1.2 -> 层叠布局 1.2.1 -> 对齐方式 1.2.2 -> Z序控制 1.3 -> 弹性布局 1.3.1…...

【论文投稿】Python 网络爬虫:探秘网页数据抓取的奇妙世界

目录 前言 一、Python—— 网络爬虫的绝佳拍档 二、网络爬虫基础&#xff1a;揭开神秘面纱 &#xff08;一&#xff09;工作原理&#xff1a;步步为营的数据狩猎 &#xff08;二&#xff09;分类&#xff1a;各显神通的爬虫家族 三、Python 网络爬虫核心库深度剖析 &…...

队列的基本用法

以下是关于 C 语言中队列的详细知识&#xff0c;包括队列的生成、相关函数使用以及其他重要概念&#xff1a; 一、队列的概念 队列是一种线性数据结构&#xff0c;它遵循先进先出&#xff08;First In First Out&#xff0c;FIFO&#xff09;的原则&#xff0c;就像日常生活中…...

网络安全VS数据安全

关于网络安全和数据安全&#xff0c;我们常听到如下两种不同声音&#xff1a; 观点一&#xff1a;网络安全是数据安全的基础&#xff0c;把当年做网络安全的那一套用数据安全再做一遍。 观点二&#xff1a;数据安全如今普遍以为是网络安全的延伸&#xff0c;实际情况是忽略数据…...

Linux(NFS服务)

赛题拓扑&#xff1a; 题目&#xff1a; NFS&#xff1a; 共享/webdata/目录。用于存储AppSrv主机的WEB数据。仅允许AppSrv主机访问该共享。 [rootstoragesrv ~]# yum install nfs-utils -y [rootstoragesrv ~]# mkdir /webdata [rootstoragesrv ~]# chmod -R ow /webdata …...

python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)边缘检测

OpenCV中边缘检测四种常用算子&#xff1a; &#xff08;1&#xff09;Sobel算子 Sobel算子是一种基于梯度的边缘检测算法。它通过对图像进行卷积操作来计算图像的梯度&#xff0c;并将梯度的大小作为边缘的强度。它使用两个3x3的卷积核&#xff0c;分别用于计…...

SSM课设-学生管理系统

【课设者】SSM课设-学生管理系统 技术栈: 后端: SpringSpringMVCMybatisMySQLJSP 前端: HtmlCssJavaScriptEasyUIAjax 功能: 学生端: 登陆 学生信息管理 个人信息管理 老师端: 多了教师信息管理 管理员端: 多了班级信息管理 多了年级信息管理 多了系统用户管理...

【Pytorch实用教程】TCN(Temporal Convolutional Network,时序卷积网络)简介

文章目录 TCN的基本特点TCN的优点TCN的应用场景典型的TCN架构总结TCN(Temporal Convolutional Network,时序卷积网络)是一种用于处理序列数据的深度学习模型,尤其适用于时间序列预测、语音识别、自然语言处理等任务。它利用卷积神经网络(CNN)来处理时序数据,相比于传统的…...

网络安全 | 什么是正向代理和反向代理?

关注&#xff1a;CodingTechWork 引言 在现代网络架构中&#xff0c;代理服务器扮演着重要的角色。它们在客户端和服务器之间充当中介&#xff0c;帮助管理、保护和优化数据流。根据代理的工作方向和用途&#xff0c;代理服务器可分为正向代理和反向代理。本文将深入探讨这两种…...

3 前端(中):JavaScript

文章目录 前言&#xff1a;JavaScript简介一、ECMAscript&#xff08;JavaScript基本语法&#xff09;1 JavaScript与html结合方式&#xff08;快速入门&#xff09;2 基本知识&#xff08;1&#xff09;JavaScript注释&#xff08;和Java注释一样&#xff09;&#xff08;2&am…...

VIT论文阅读与理解

transform网络结构 vision transform网络结构 图1&#xff1a;模型概述。我们将图像分割成固定大小的补丁&#xff0c;线性嵌入每个补丁&#xff0c;添加位置嵌入&#xff0c;并将结果向量序列馈送到标准Transformer编码器。为了执行分类&#xff0c;我们使用标准方法向序列中添…...

JavaScript笔记APIs篇01——DOM获取与属性操作

黑马程序员视频地址&#xff1a;黑马程序员前端JavaScript入门到精通全套视频教程https://www.bilibili.com/video/BV1Y84y1L7Nn?vd_source0a2d366696f87e241adc64419bf12cab&spm_id_from333.788.videopod.episodes&p78https://www.bilibili.com/video/BV1Y84y1L7Nn?…...

SQL表间关联查询详解

简介 本文主要讲解SQL语句中常用的表间关联查询方式&#xff0c;包括&#xff1a;左连接&#xff08;left join&#xff09;、右连接&#xff08;right join&#xff09;、全连接&#xff08;full join&#xff09;、内连接&#xff08;inner join&#xff09;、交叉连接&…...

select函数

系统调用 select()可用于执行 I/O 多路复用操作&#xff0c;调用 select()会一直阻塞&#xff0c;直到某一个或多个文件描述符成为就绪态&#xff08;可以读或写&#xff09;。其函数原型如下所示&#xff1a; #include <sys/select.h> int select(int nfds, fd_set *re…...

建造者模式(或者称为生成器(构建器)模式)

一、什么是建造者模式&#xff1f; 将复杂对象的构建与表示进行分离&#xff0c;使得统一的构建过程&#xff0c;可以创建出不同的对象表现模式 就是将复杂对象里面的成员变量&#xff0c;设置不同的值&#xff0c;使得生成出来的对象拥有不同的属性值&#xff1b; 二、特点…...

【深度学习】Huber Loss详解

文章目录 1. Huber Loss 原理详解2. Pytorch 代码详解3.与 MSELoss、MAELoss 区别及各自优缺点3.1 MSELoss 均方误差损失3.2 MAELoss 平均绝对误差损失3.3 Huber Loss 4. 总结4.1 优化平滑4.2 梯度较好4.3 为什么说 MSE 是平滑的 1. Huber Loss 原理详解 Huber Loss 是一种结合…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...