轉自:網路

什麼是libc?

libc是C語言標準庫(C standard library)的縮寫,它是C語言程式開發中常用的庫之一。libc提供了一系列的函式和常量,用於處理字串、記憶體操作、輸入輸出、數學運算、日期時間等常見的程式設計任務。C語言標準庫包含了一些核心的標頭檔案,如<stdio.h>、<stdlib.h>、<string.h>等,這些標頭檔案定義了許多常用的函式和型別。透過包含這些標頭檔案,開發者可以使用庫中提供的函式來完成各種任務,而無需從頭開始編寫相關的程式碼。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. 零長度和變數長度陣列:
// 零長度陣列
structZeroLengthArray {
int
len;
int
data[
0
];
// 零長度陣列
};
// 變數長度陣列
voidvariableLengthArray(int size)
{
intarray
[size];
// 變數長度陣列
}
2. case範圍:
int
number =
5
;
switch
(number) {
case1
...
5
:
// 使用範圍匹配多個case標籤
printf
(
"Number is between 1 and 5\n"
);
break
;
case6
:
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<stdio.h>
#include<stdarg.h>
#define SUM(...) sum(__VA_ARGS__)
intsum(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;
}
intmain()
{
int
result = SUM(
1
,
2
,
3
,
4
,
5
);
printf
(
"Sum: %d\n"
, result);
return0
;
}
這些示例程式碼展示了GNU C的擴充套件特性的用法。請注意,這些特性可能不被所有C編譯器支援,因此在使用時請確保目標平臺和編譯器的相容性。
libc.so.6的坑
接下來說一下我幾年前遇到的一個坑在移植CentOS 7.9到RK3399上,並使用RK提供的updateEngine進行OTA升級時,遇到了一些問題。首先,編譯生成的updateEngine工具在CentOS上無法執行,缺少libpng.so庫。為了解決這個問題,嘗試將libpng.so庫複製到系統中,但是發現libc.so等庫的版本太低。因此決定升級這些庫。下載了glibc的原始碼,並按照以下步驟進行編譯:1. 執行../configure2. 執行make3. 執行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或更高版本,因為它們的系統庫已經比較新了。請記住,更新系統存在一定的風險,需要謹慎操作。