库有三种使用形式:
- 静态库,静态库的代码在编译时就已链接到应用程序中,占用代码空间
- 共享库,共享库只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。
- 动态库,动态库是共享库的另一种变化形式,它也是在程序运行时载入,但与共享库不同的是,使用的库函数不是在程序运行时开始,而是在程序中的语句需要使用该函数时才载入。动态库可以在程序运行时释放动态库所占用的内存空间。
现在来看一下编译时如何生成静态库与共享库
#目录为/home/test
#动态库:libtest.so #静态库:libtest.a all:libtest.so libtest.a
libtest.so: $(OBJS) gcc -shared -o $@ $^ -lgcc libtest.a: $(OBJS) ar arc -o $@ $^
#其它目录中的文件通过修改以下Makefile即可使用到该动态库
LDFLAGS += -L/home/test -ltest
|
下面,以实例的方式说明动态库的使用方法
#/home/dll/call.c
int callFunc() { printf("This is callFunc.\n");
return 0; }
#/home/dll/test.c int testFunc() { callFunc(); printf("This is callFunc.\n");
return 0; }
|
编译为动态库libcall.so
gcc -shared -fpic -Wall -o libcall.so callFunc.c testFunc.c
|
现在编写代码使用动态库函数调用该动态库
#/home/dll/load.c
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h>
void *functionLib; int (*function)(); const char *dlError;
int main() { int rc;
functionLib = dlopen("./libcall.so", RTLD_LAZY); dlError = dlError(); if(dlError) exit(1);
function = dlsym(functionLib, "testFunc"); dlError = dlError(); if(dlError) exit(1);
rc = (*function)(); dlError = dlError(); if(dlError) exit(1); }
|
编译该文件
gcc load.c -ldl -o load
运行结果:
This is callFunc.
This is testFunc.
|
除了按以上方法使用动态库函数,我们还可以在编译时链接动态库,这样,就可以无需使用库函数直接调用这些库中的函数,如下所示:
#/home/dll/m.c
#include <stdio.h>
int main() { testFunc();//该函数在libcall.so中 return 0; }
|
编译如下:
#生成目标文件m.o
gcc -c -o m.o m.c #链接动态库libcall.so,记录于ELF
#记得要将libcall.so加入到目标机器的lib目录中,如/usr/lib gcc -o m m.o -L/home/dll -lcall
|
此时运行m后,将直接调用
testFunc函数,从而实现库存函数调用的功能
阅读(724) | 评论(0) | 转发(0) |