专栏名称: Linux爱好者
伯乐在线旗下账号,「Linux爱好者」专注分享 Linux/Unix 相关内容,包括:工具资源、使用技巧、课程书籍等。
目录
相关文章推荐
Linux爱好者  ·  “宇宙最强”开源代码编辑器——VS ... ·  1 周前  
51好读  ›  专栏  ›  Linux爱好者

libc.so.6小入门

Linux爱好者  · 公众号  · linux  · 2024-08-16 11:50

正文

转自:网络


什么是libc?

libc是C语言标准库(C standard library)的缩写,它是C语言程序开发中常用的库之一。libc提供了一系列的函数和常量,用于处理字符串、内存操作、输入输出、数学运算、日期时间等常见的编程任务。

C语言标准库包含了一些核心的头文件,如等,这些头文件定义了许多常用的函数和类型。通过包含这些头文件,开发者可以使用库中提供的函数来完成各种任务,而无需从头开始编写相关的代码。

libc的实现会因不同的操作系统和编译器而有所差异,但它们都遵循C语言标准,提供了一致的接口和功能。开发者可以在编写C语言程序时直接调用这些库函数,以提高开发效率并简化代码编写过程。


glibc、glib、libc之间的区别?

glibc、glib和libc是三个不同的库,它们在不同的上下文中有不同的含义和作用。下面是它们之间的区别:

glibc(GNU C库):glibc是GNU发布的C语言标准库,也被称为GNU libc。它是Linux系统中最基础的API之一,几乎所有的运行库都依赖于glibc。glibc不仅封装了Linux操作系统提供的系统服务,还提供了许多其他必要功能的实现,如字符串处理、内存管理、文件操作、网络通信、多线程支持等。glibc的实现遵循C语言标准,提供了一致的接口和功能,可以帮助开发者快速编写高效、可靠的程序。在Linux系统中,glibc扮演着非常重要的角色,是Linux系统运行的基石之一。

glib:glib是一个通用的C语言工具库,它是为了解决C语言中一些常见问题而设计的。glib提供了一些数据结构、线程支持、内存管理、字符串处理、文件操作等功能。它是一个跨平台的库,可以在不同的操作系统上使用。glib被广泛应用于GNOME桌面环境和许多其他开源项目中。

libc(ANSI C标准库):libc是C语言标准库(C standard library)的缩写,它是C语言程序开发中常用的库之一。libc提供了一系列的函数和常量,用于处理字符串、内存操作、输入输出、数学运算、日期时间等常见的编程任务。它是C语言程序的基础库,提供了许多常用的功能和接口。

总结来说,glibc是Linux系统中最底层的C语言标准库,提供了丰富的系统服务和功能实现;glib是一个通用的C语言工具库,提供了一些常见问题的解决方案;而libc是C语言标准库,提供了基础的函数和常量,用于处理常见的编程任务。


ANSI C和GNU C的区别

ANSI C和GNU C是两种不同的C语言标准和实现,它们之间的区别如下:

ANSI C:ANSI C是C语言的标准化版本,由美国国家标准协会(ANSI)于1989年发布。ANSI C标准规定了C语言的语法、语义和标准库,使得不同的编译器可以在不同的平台上生成相同的代码。ANSI C标准化了C语言,使得C语言成为一种通用的编程语言,被广泛应用于系统编程、嵌入式系统、网络编程等领域。


GNU C:GNU C是GNU项目发布的C语言编译器,也称为gcc。GNU C是ANSI C的扩展版本,它提供了一些ANSI C没有定义的语言特性和扩展库。GNU C编译器是一个跨平台的编译器,可以在不同的操作系统上使用,如Linux、Windows、Mac OS等。GNU C编译器是开源的,可以自由使用和修改。


例如新增语法

1.零长度和变量长度数组

2.case范围

3.语句表达式

4.typeof关键字

5.可变参数宏

...还有很多,自己查

下面是一些示例代码来演示GNU C的扩展特性:

1. 零长度和变量长度数组:

// 零长度数组
struct ZeroLengthArray {
int len;
int data[0]; // 零长度数组
};
// 变量长度数组
void variableLengthArray(int size) {
int array[size]; // 变量长度数组
}

2. case范围:

int number = 5;
switch (number) {
case 1 ... 5: // 使用范围匹配多个case标签
printf("Number is between 1 and 5\n");
break;
case 6:
printf("Number is 6\n");
break;
default:
printf("Number is not in the range\n");
break;
}

3. 语句表达式:

int result = ({
int a = 5;
int b = 10;
a + b; // 语句表达式,返回a + b的结果
});
printf("Result: %d\n", result);

4. typeof关键字:

int number = 10;
typeof(number) newNumber; // 使用typeof获取number的类型
newNumber = number + 5;
printf("New Number: %d\n", newNumber);

5. 可变参数宏:

#include 
#include
#define SUM(...) sum(__VA_ARGS__)
int sum(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++) {
total += va_arg(args, int);
}
va_end(args);
return total;
}
int main() {
int result = SUM(1, 2, 3, 4, 5);
printf("Sum: %d\n", result);
return 0;
}

这些示例代码展示了GNU C的扩展特性的用法。请注意,这些特性可能不被所有C编译器支持,因此在使用时请确保目标平台和编译器的兼容性。


libc.so.6的坑

接下来说一下我几年前遇到的一个坑

在移植CentOS 7.9到RK3399上,并使用RK提供的updateEngine进行OTA升级时,遇到了一些问题。

首先,编译生成的updateEngine工具在CentOS上无法运行,缺少libpng.so库。为了解决这个问题,尝试将libpng.so库拷贝到系统中,但是发现libc.so等库的版本太低。因此决定升级这些库。

下载了glibc的源码,并按照以下步骤进行编译:

1. 运行../configure

2. 运行make

3. 运行make install

如果出现错误,您通过搜索解决了这些问题


升级完成后,updateEngine可以正常使用。然而,在发布给测试进行测试,但是在过程中遇到了一些问题。例如,hwclock工具出现段错误,lspci工具重定向出错,以及lspci -vvv | grep命令失败并报错。此外,运行yum update导致系统崩溃,卸载软件时会意外卸载其他系统工具等。

然后发现旧版本的CentOS不存在这些问题,并且可以通过重新编译hwclock和lspci等工具来解决。然而,由于yum update会导致系统不稳定,最后决定还原回去,问题得到解决。

反思方案

针对updateEngine的问题,有三种解决方案:

1.使用CentOS的库来编译updateEngine,只要它不依赖于较高版本的libc特性。可以修改Makefile来实现这一点。


2.进行静态编译,即将updateEngine可执行文件所需的动态链接库部分提取出来,链接到可执行文件中,使其在运行时不依赖于动态链接库。同样,可以修改Makefile来实现静态编译。


3.修改配置文件去除updateEngine的UI界面所需的libpng库,因为并不需要它。

方案选择

最后选择了第三种方法

总结起来,CentOS之所以使用较旧的系统库,是为了保证稳定性,服务器OS首先centos。如果需要更新的话,可以考虑使用CentOS 8或更高版本,因为它们的系统库已经比较新了。请记住,更新系统存在一定的风险,需要谨慎操作。


推荐阅读  点击标题可跳转

1、全面了解DPDK

2、Nginx一网打尽:代理、缓存、黑白名单、跨域、高可用、性能

3、嫌邻居放歌太吵,开发者偷用「树莓派+AI」黑进音箱:干扰音频,使其不得不关