Linux 中的应用程序以以下两种方式之一链接到外部函数:要么在构建时与静态库( lib*.a)静态地链接,并且将库代码包含在该应用程序的可执行文件里;要么在运行时与共享库( lib*.so)动态地链接。通过动态链接装入器,将动态库映射进应用程序的可执行内存中。在启动应用程序之前,动态链接装入器将所需的共享目标库映射到应用程序的内存,或者使用系统共享的目标并为应用程序解析所需的外部引用。现在应用程序就可以运行了。
先介绍静态库:
静态函数库实际上就是简单的一个普通的目标文件的集合,一般来说习惯用“.a”作为文件的后缀。可以用ar这个程序来产生静态函数库文件。Ar 是archiver的缩写。静态函数库现在已经不在像以前用得那么多了,主要是共享函数库与之相比较有很多的优势的原因。慢慢地,大家都喜欢使用共享函数库了。不过,在一些场所静态函数库仍然在使用,一来是保持一些与以前某些程序的兼容,二来它描述起来也比较简单。
静态库函数允许程序员把程序link起来而不用重新编译代码,节省了重新编译代码的时间。不过,在今天这么快速的计算机面前,一般的程序的重新编译也花费不了多少时间,所以这个优势已经不是像它以前那么明显了。静态函数库对开发者来说还是很有用的,例如你想把自己提供的函数给别人使用,但是又想对函数的源代码进行保密,你就可以给别人提供一个静态函数库文件。理论上说,使用ELF格式的静态库函数生成的代码可以比使用共享函数库(或者动态函数库)的程序运行速度上快一些,大概1-5%。
假设有下面几个文件:String.h,Strlen.c,Strlnen.c:
String.h,声明相关函数原形;/***********************************Filename : String.hDescription :Author : HCJDate : 2006-5-7************************************/int Strlen(char *pStr);int StrNlen(char *pStr, unsigned long ulMaxLen);Strlen.c:函数Strlen的实现,获取给定字符串的长度;
/**************************************Filename : get string lengthDescription : Author : HCJDate : 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.cDescription: get input string length,if string large max length input return max length, else real lengthAuthor: HCJDate : 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.cDescription: test static/dynamic libraryAuthor: HCJDate : 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;}
这篇文章也不错,就是不太整洁:
转自:http://www.cppblog.com/prayer/archive/2009/08/24/94325.html