先来说说C/C++编译过程
- 编译: 检查语句符号定义,将C/C++代码翻译生成中间语言。
- 链接: 将中间代码整合,生成可执行的二进制代码。
简单的说,库文件都是一种特殊的中间语言文件,静态库还是一种特殊格式的归档文件(打包的文件)。
使用静态库:
1. 先编写库函数
#ifndef _PRINT_TEST_H_ #define _PRINT_TEST_H_
#ifdef __cplusplus
extern "C"
{
#endif extern int test_a;
extern void print_test();
extern void print_data_a(); #ifdef __cplusplus
}
#endif #endif
print_test.h
#ifdef __cplusplus
extern "C"
{
#endif #include <stdio.h> void print_test()
{
printf("print_test\n");
} int test_a = ;
void print_data_a()
{
printf("data in libtest test_a = %d\n", test_a++);
} #ifdef __cplusplus
}
#endif
print_test.c
2. 主函数文件
#include "print_test.h" int main()
{
print_test();
print_data_a();
print_data_a();
print_data_a();
print_data_a();
print_data_a();
return ;
}
main.c
3. 编译库函数
4. 打包库
5. 编译主函数和运行
tips: 静态库文件命名通常以lib开头,链接库时直接 -l库名。
静态库的优点在于一次编译生成目标(main)后,这个目标是一个独立的二进制文件,而不用考虑其运行环境。
使用动态库
1. 编译库
ps: 很奇怪一点是,dltest.so被赋予了可执行权限。
2. 编译主函数
tips: 最好将自己要用的动态链接放到系统默认的库目录下,否则运行目录没有相应的库文件会报错。
动态库优点在于,生成的目标更小;当库文件更新时,只要原来用到的符号地址不变,目标可以继续运行,并且伴随着库一起更新。这样动态库的更新可以与目标的更新相互独立进行。