Linux C/C++ .so .a 文件生成及使用
.so 文件 - 动态函数库
名字一般是libxxx.so,动态函数库在编译的时候 并没有被编译进目标代码中,程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。
linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib
动态函数库与Windows下的DLL类似,是在程序运行时动态连接,多个进程可以连接同一个共享库。
多个c文件编译成一个so文件命令是为:
$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
选项:
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-L.:表示要连接的库在当前目录中
-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字(test)前面加上lib,后面加上.so来确定库的名称: libtest.so
使用:
1、IDE(CodeBlocks):在项目中添加所有函数库的头文件(.h),在Linker setting 中添加.so文件.
2、命令行:将main.c与动态库libtest.so链接生成执行文件mainexc:
$ gcc main.c -L. -ltest -o mainexc
.so文件路径
命令行下默认查找 .so 文件的路径基本为系统路径,lib或者usr/lib等,因此,执行./mainexc 会出现错误:
xx.so, cannot open shared object file: No such file or directory
解决方法:
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。
如果有root权限,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的
.a 文件 - 静态函数库
名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中
优点是编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了
缺点是如果静态函数库改变了,那么程序必须重新编译
.c 文件编译成 .o(.object)文件:
$gcc -c test_a.c $gcc -c test_b.c $gcc -c test_c.c
多个.o 文件编译成一个 a 文件命令是为:
$ ar -cr libtest.a test_a.o test_b.o test_c.o
命令行调用:
$ gcc -o mainexc main.c -L. -ltest
============================================================
测试代码:
1so_test.h
2#ifndef SO_TEST_H_INCLUDED
3#define SO_TEST_H_INCLUDED
4
5#include <stdio.h>
6#include <stdlib.h>
7
8void test_a();
9void test_b();
10void test_c();
11
12#endif // SO_TEST_H_INCLUDED
13test_a.c:
14
15#include "so_test.h"
16
17void test_a()
18{
19printf("this is in test_a.../n");
20}
21
22test_b.c:
23
24#include "so_test.h"
25
26void test_b()
27{
28printf("this is in test_b.../n");
29}
30
31test_a.c:
32
33#include "so_test.h"
34
35void test_c()
36{
37printf("this is in test_c.../n");
38}