Linux下动静态库的打包与使用指南(C/C++)
什么是库
在软件开发中,我们常常会将一些常用的代码封装成函数或类。如果这些函数或类需要在多个程序中使用,那么将其打包成一个库以供其他程序调用就是一个不错的选择。库分为动态库和静态库两种类型。
静态库和动态库的区别
- 静态库
静态库是指在程序编译时,代码就已经被编译进了可执行文件中。因此,可执行文件体积较大,但是在程序运行时,不需要加载其他 DLL 文件,直接运行即可。这就保证了程序运行的稳定性。
- 动态库
与静态库不同,动态库在程序运行时才会被加载。这样,可执行文件不需要包含整个库代码,减小了可执行文件的体积。但是,程序运行时,若是要使用到动态库中的函数代码,就需要先找到动态库所在的位置,然后再去加载其中的函数代码,这样会稍微增加程序启动的时间,但是这样会减少内存的使用,节省硬盘空间。
静态库的打包与使用
静态库打包
静态库可以通过 gcc 命令行进行打包:
$ gcc -c -o mylib.o mylib.c //这里是将源文件编译为目标文件的语句
$ ar -r libmylib.a mylib.o //将编译好的目标文件打包成静态库的语句
- -c 表示编译源文件
- -o mylib.o 表示将源文件编译为目标文件
- ar -r 表示将目标文件打包为静态库
- libmylib.a 表示静态库的名称
静态库使用
静态库使用方法,可以在 gcc 命令行中添加 -lmylib 的参数,其中 -l 表示连接操作(链接器),后面接静态库的名称(去掉前面的"lib"和后面的".a")。例如:
$ gcc -o myapp myapp.c -lmylib
这个命令将会将 myapp.c 编译为目标文件 myapp,并将 myapp 和库中的函数一起连接,生成可执行文件。
动态库的打包与使用
动态库打包
动态库同样可以通过 gcc 命令行进行打包,不过需要特别标注:
$ gcc -fPIC -shared -o libmylib.so mylib.c
- -fPIC 表示生成与位置无关的代码(PIC)。
- -shared 表示生成动态库。
- -o libmylib.so 表示生成的动态库名称。
动态库使用
动态库使用方法类似于静态库的使用,使用 -lmylib 的参数,不过需要加上 -L 和库文件所在目录的路径。
例如,若库文件在 /usr/local/lib 目录下,可以使用下面的命令运行程序:
$ gcc -o myapp myapp.c -L/usr/local/lib -lmylib
实例说明
- 静态库实例说明
在示例代码中,我们假设存在一个 mylib.c 文件,包含如下代码:
int square(int n) { return n * n; }
使用下面的命令编译 mylib.c 文件并打包生成静态库 libmylib.a:
$ gcc -c -o mylib.o mylib.c
$ ar -r libmylib.a mylib.o
然后,我们可以再编写一个主程序 myapp.c,用来调用 mylib 中的函数:
#include <stdio.h>
int square(int); //声明静态库中的函数
int main(int argc, char *argv[]) {
int n = 5;
printf("%d的平方为%d\n", n, square(n)); //调用静态库中的函数
return 0;
}
最后,使用下面的命令编译 myapp.c 文件:
$ gcc -o myapp myapp.c -L. -lmylib
其中,-L. 表示将当前目录加入到库文件的搜索路径。-lmylib 表示链接到 libmylib.a 静态库文件。
执行 myapp 程序:
$ ./myapp
输出结果为:5的平方为25。
- 动态库实例说明
继续以 mylib.c 为例。我们可以使用下面的命令编译 mylib.c 文件并生成动态库 libmylib.so:
$ gcc -fPIC -shared -o libmylib.so mylib.c
然后,我们可以再编写一个主程序 myapp.c,用来调用 mylib 中的函数:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
typedef int (*f_type)(int); //声明函数指针类型
int main(int argc, char *argv[]) {
void *handle;
char *error;
int (*f)(int);
int n = 5;
handle = dlopen("./libmylib.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror();
f = (f_type)dlsym(handle, "square");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
printf("%d的平方为%d\n", n, (*f)(n));
dlclose(handle);
return 0;
}
编译并执行:
$ gcc -o myapp myapp.c -ldl
$ ./myapp
输出结果为:5的平方为25。
这里需要注意一下,使用动态库时,需要使用 dlopen() 函数打开库文件,使用 dlsym() 函数获取指向被调用函数的指针,使用 dlclose() 函数关闭库文件。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Linux下动静态库的打包与使用指南(C/C++) - Python技术站