静态库
静态库在编译时拷贝到目标文件中,当多个应用程序同时引用同一个静态库时,内存中会有调用函数的多个副本。
使用实例:
头文件mylib.h
#ifndef __MYLIB_H__
#define __MYLIB_H__
void welcome();
void outstring(const char *);
#endif
|
源文件mylib.h
#include “mylib.h”
#include <stdio.h>
void welcome()
{
printf("wellcome to libmylib\n");
}
void outstring(const char *str)
{
if(str != NULL)
printf("%s\n", str)
}
|
编译mylib.c生成目标文件
gcc -o mylib.o -c mylib.c
|
将目标文件加入到静态库中
ar -rcs libmylib.a mylib.o
|
测试程序test.c
#include "mylib.h"
#include <stdio.h>
int main()
{
printf("creat and use library:\n");
welcome();
outstring("It's successful");
}
|
将静态库拷贝到linux的库目录下(/usr/lib 或 /lib)
sudo cp libmylib.a /usr/lib/
|
编译测试程序
运行程序
程序输出
creat and use static library:
welcome to my static lib
It
|
动态库
动态库在程序开始运行后调用库中函数时才会被载入,被调用函数在内存中只有一个副本,并且动态库可以在程序运行期间释放动态库所占用的内存。
使用实例把mylib.c创建成一个动态库
gcc -fPIC -shared -o libmylib.so mylib.c
|
编译测试程序(引用动态库时必须含有库的路径)
运行a.out结果同上
动态库系统函数void *dlopen(const char *filename, int flag); //打开一个指定名称的动态库,并返回一个句柄
void *dlsym(void *handle, char *symbol); //根据动态库的句柄与函数名,返回函数名对应的函数地址
int dlclose(void *handle); //关闭动态库,handle是调用dlopen返回的句柄
const char *dlerror(void);
|
dlopen函数的flag:
RTLD_LAZY //在dlopen返回前,对于动态库中存在的未定义变量(如外部变量extern,也可以时函数)不执行解析
RTLD_NOW //在dlopen返回前,解析出每个未定义的变量的地址,如果解析不出来,dlopen返回NULL
RTLD_GLOBAL //使库中被解析出来的变量在随后的其他链接库中也可以使用,即全局有效
|
演示代码
1 #include 2 #include 3 4 int main() 5 { 6 void *handle; 7 char *error; 8 void (*welcome)(); 9 10 if ((handle = dlopen("./mylib.so", RTLD_LAZY)) != NULL ) { 11 welcome = dlsym(handle, "welcome"); 12 if ( (error = dlerror()) == NULL ) { 13 welcome(); 14 dlclose(handle); 15 } 16 } 17 }
|
编译运行程序(mylib.so在当前目录下)
[davy@HD points]$ gcc testso.c -ldl
[davy@HD points]$ ./a.out
welcome to my static lib
|