linux靜態/動態鏈接庫的創建和使用
和Windows系統一樣Linux也有靜態/動態鏈接庫,下面介紹創建和使用方法:
假設有下面幾個文件:
頭文件String.h,聲明相關函數原形,內容如下:
Strlen.c:函數Strlen的實現,獲取給定字符串的長度,內容如下:
Strlnen.c:函數StrNlen的實現,獲取給定字符串的長度,假如輸入字符串的長度大于指定的最大長度,則返回最大長度,否者返回字符串的實際長度,內容如下:
生成靜態庫:
利用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已經成功生成。
/***********************************
Filename : String.h
Description :
Author : HCJ
Date : 2006-5-7
************************************/
int Strlen(char *pStr);
int StrNlen(char *pStr, unsigned long ulMaxLen);
/**************************************
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;
}
**********************************************
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 -fpic -shared -o libstr.so Strlen.c Strnlen.c
-fpic 使輸出的對象模塊是按照可重定位地址方式生成的。
-shared指定把對應的源文件生成對應的動態鏈接庫文件libstr.so文件。
對應的鏈接庫已經生成,下面看一下如何使用對應的鏈接庫。
靜態庫的使用:
假設有下面的文件要使用對應的的靜態庫:
編譯生成對應的目標文件:
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;
}
動態庫的分為隱式調用和顯式調用兩種調用方法:
隱式調用的使用使用方法和靜態庫的調用差不多,具體方法如下:
gcc -c -I/home/hcj/xxxxxxxx main.c
gcc -o main1 -L/home/hcj/xxxxxxxx main.o libstr.so //這里是*.so
在這種調用方式中,需要維護動態鏈接庫的配置文件/etc/ld.so.conf來讓動態鏈接庫為系統所使用,通常將動態鏈接庫所在目錄名追加到動態鏈接庫配置文件中。否則在執行相關的可執行文件的時候就會出現載入動態鏈接庫失敗的現象。在編譯所引用的動態庫時,可以在gcc采用 –l或-L選項或直接引用所需的動態鏈接庫方式進行編譯。在Linux里面,可以采用ldd命令來檢查程序依靠共享庫。
顯式調用:
/*****************************************
FileName: main2.c
Description: test static/dynamic library
Author: HCJ
Date : 2005-5-7
******************************************/
#include<stdio.h>
#include<dlfcn.h>
int main(int argc, char* argv[])
{
//define function pointor
int (*pStrlenFun)(char* pStr); //聲明對應的函數的函數指針
int (*pStrnlenFun)(char* pStr, int ulMaxLen);
char str[] = {"hello world"};
unsigned long ulLength = 0;
void *pdlHandle;
char *pszErr;
pdlHandle = dlopen("./libstr.so", RTLD_LAZY); //加載鏈接庫/libstr.so
if(!pdlHandle)
{
printf("Failed load library/n");
}
pszErr = dlerror();
if(pszErr != NULL)
{
printf("%s/n", pszErr);
return 0;
}
//get function from lib
pStrlenFun = dlsym(pdlHandle, "Strlen"); //獲取函數的地址
pszErr = dlerror();
if(pszErr != NULL)
{
printf("%s/n", pszErr);
return 0;
}
pStrnlenFun = dlsym(pdlHandle, "StrNlen");
pszErr = dlerror();
if(pszErr != NULL)
{
printf("%s/n", pszErr);
return 0;
}
printf("The string is : %s/n", str);
ulLength = pStrlenFun(str); //調用相關的函數
printf("The string length is : %d(use Strlen)/n", ulLength);
ulLength = pStrnlenFun(str, 10);
printf("The string length is : %d(use StrNlen)/n", ulLength);
dlclose(pdlHandle);
return 0;
}
gcc -o mian2 -ldl main2.c
|
新聞熱點
疑難解答