王朝网络
分享
 
 
 

Linux静态/动态链接库的创建和使用

王朝system·作者佚名  2008-05-31
宽屏版  字体: |||超大  

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

用gcc编译对应的源文件生成可执行文件,-ldl选项,表示生成的对象模块需要使用共享库。执行对应得文件同样可以得到正确的结果。

相关函数的说明如下:

(1)dlopen()

第一个参数:指定共享库的名称,将会在下面位置查找指定的共享库。

-环境变量LD_LIBRARY_PATH列出的用分号间隔的所有目录。

-文件/etc/ld.so.cache中找到的库的列表,用ldconfig维护。

-目录usr/lib。

-目录/lib。

-当前目录。

第二个参数:指定如何打开共享库。

-RTLD_NOW:将共享库中的所有函数加载到内存

-RTLD_LAZY:会推后共享库中的函数的加载操作,直到调用dlsym()时方加载某函数

(2)dlsym()

调用dlsym时,利用dlopen()返回的共享库的phandle以及函数名称作为参数,返回要加载函数的入口地址。

(3)dlerror()

该函数用于检查调用共享库的相关函数出现的错误。

这样我们就用简单的例子说明了在Linux下静态/动态库的创建和使用。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有