Linux 中的應用程序以以下兩種方式之一鏈接到外部函數:要么在構建時與靜態庫( lib*.a)靜態地鏈接,并且將庫代碼包含在該應用程序的可執行文件里;要么在運行時與共享庫( lib*.so)動態地鏈接。通過動態鏈接裝入器,將動態庫映射進應用程序的可執行內存中。在啟動應用程序之前,動態鏈接裝入器將所需的共享目標庫映射到應用程序的內存,或者使用系統共享的目標并為應用程序解析所需的外部引用。現在應用程序就可以運行了。
先介紹靜態庫:
靜態函數庫實際上就是簡單的一個普通的目標文件的集合,一般來說習慣用“.a”作為文件的后綴??梢杂?/span>ar這個程序來產生靜態函數庫文件。Ar 是archiver的縮寫。靜態函數庫現在已經不在像以前用得那么多了,主要是共享函數庫與之相比較有很多的優勢的原因。慢慢地,大家都喜歡使用共享函數 庫了。不過,在一些場所靜態函數庫仍然在使用,一來是保持一些與以前某些程序的兼容,二來它描述起來也比較簡單。
靜態庫函數允許程序員把程序link起來而不用重新編譯代碼,節省了重新編譯代碼的時間。不過,在今天這么快速的計算機面前,一般的程序的重新 編譯也花費不了多少時間,所以這個優勢已經不是像它以前那么明顯了。靜態函數庫對開發者來說還是很有用的,例如你想把自己提供的函數給別人使用,但是又想 對函數的源代碼進行保密,你就可以給別人提供一個靜態函數庫文件。理論上說,使用ELF格式的靜態庫函數生成的代碼可以比使用共享函數庫(或者動態函數 庫)的程序運行速度上快一些,大概1-5%。
假設有下面幾個文件:String.h,Strlen.c,Strlnen.c:
String.h,聲明相關函數原形;
/***********************************
Filename : String.h
Description :
Author : HCJ
Date : 2006-5-7
************************************/
int Strlen(char *pStr);
int StrNlen(char *pStr, unsigned long ulMaxLen);
Strlen.c:函數Strlen的實現,獲取給定字符串的長度;
/**************************************
Filename : get string length
Description :
Author : HCJ
Date : 2006/5/7
**************************************/
#include<stdio.h>
#include<assert.h>
int Strlen(char *pStr)
{
unsigned long ulLength;
assert(NULL != pStr);
ulLength = 0;
while(*pStr++)
{
ulLength++;
}
return ulLength;
}
Strlnen.c:函數StrNlen的實現,獲取給定字符串的長度,如果輸入字符串的長度大于指定的最大長度,則返回最大長度,否者返回字符串的實際長度;
/**********************************************
Fileneme: mystrnlen.c
Description: get input string length,if string large
max length input return max length,
else real length
Author: HCJ
Date : 2006-5-7
**********************************************/
#include<stdio.h>
#include<assert.h>
int StrNlen(char *pStr, unsigned long ulMaxLen)
{
unsigned long ulLength;
assert(NULL != pStr);
if(ulMaxLen <= 0)
{
printf("Wrong Max Length!\n");
return -1;
}
ulLength = 0;
while(*pStr++ && ulLength < ulMaxLen)
{
ulLength++;
}
return ulLength;
}
生成靜態鏈接庫:
利用GCC生成對應目標文件:
#>gcc –c Strlen.c Strnlen.c
如果對應的文件沒有錯誤,gcc會對文件進行編譯生成Strlen.o和Strnlen.o兩個目標文件(相當于windows下的obj文件)。然后用ar創建一個名字為libstr.a的庫文件,并把Strlen.o 和Strnlen.o的內容插入到對應的庫文件中。,相關命令如下:
#>ar –rc libstr.a Strlen.o Strnlen.o
命令執行成功以后,對應的靜態庫libstr.a已經成功生成。
靜態庫的使用:
假設有下面的文件要使用對應的的靜態庫:
編譯生成對應的目標文件:
#>gcc -c -I/home/hcj/xxxxxxxx main.c
生成可執行文件:
#>gcc -o main1 -L/home/hcj/xxxxxxxx main.o libstr.a
其中-I/home/hcj/xxxxxxxx和-L/home/hcj/xxxxxxxx是通過-I和-L指定對應的頭文件和庫文件的路徑。libstr.a是對應的靜態庫的名稱。這樣對應的靜態庫已經編譯到對應的可執行程序中。執行對應的可執行文件便可以對應得函數調用的結果。
/*****************************************
FileName: main.c
Description: test static/dynamic library
Author: HCJ
Date : 2005-5-7
******************************************/
#include<stdio.h>
#include “String.h” //靜態庫對應函數的頭文件
int main(int argc, char* argv[])
{
char str[] = {"hello world"};
unsigned long ulLength = 0;
printf("The string is : %s\n", str);
ulLength = Strlen(str);
printf("The string length is : %d(use Strlen)\n", ulLength);
ulLength = StrNlen(str, 10);
printf("The string length is : %d(use StrNlen)\n", ulLength);
return 0;
}
這篇文章也不錯,就是不太整潔: