GCC生成动态链接库(.so文件):-shared和-fPIC选项

本文详细介绍了Linux下动态链接库(.so文件)的创建与使用方法,包括GCC命令行参数-shared和-fPIC的作用,以及如何将动态链接库链接到可执行文件中。

Linux 下动态链接库(shared object file,共享对象文件)的文件后缀为.so,它是一种特殊的目标文件(object file),可以在程序运行时被加载(链接)进来。使用动态链接库的优点是:程序的可执行文件更小,便于程序的模块化以及更新,同时,有效内存的使用效率更高。

GCC 生成动态链接库

如果想创建一个动态链接库,可以使用 GCC 的-shared选项。输入文件可以是源文件、汇编文件或者目标文件。

另外还得结合-fPIC选项。-fPIC 选项作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code);这样一来,产生的代码中就没有绝对地址了,全部使用相对地址,所以代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

例如,从源文件生成动态链接库:

$ gcc -fPIC -shared func.c -o libfunc.so

 从目标文件生成动态链接库:

$ gcc -fPIC -c func.c -o func.o
$ gcc -shared func.o -o libfunc.so

 -fPIC 选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码。

GCC 将动态链接库链接到可执行文件

如果希望将一个动态链接库链接到可执行文件,那么需要在命令行中列出动态链接库的名称,具体方式和普通的源文件、目标文件一样。请看下面的例子:

$ gcc main.c libfunc.so -o app.out

 将 main.c 和 libfunc.so 一起编译成 app.out,当 app.out 运行时,会动态地加载链接库 libfunc.so。

当然,必须要确保程序在运行时可以找到这个动态链接库。你可以将链接库放到标准目录下,例如 /usr/lib,或者设置一个合适的环境变量,例如 LIBRARY_PATH。不同系统,具有不同的加载链接库的方法。

 

转载于:https://www.cnblogs.com/liuzhenbo/p/11030946.html

1)首先进入第二个实验目录second,然后创建4个文件add.c, sub.c,div.c,test.h /*****add.c*****/ #include "test.h" int add(int a,int b) { return a + b; } /*****sub.c*****/ #include "test.h" int sub(int a,int b) { return a - b; } /*****div.c*****/ #include "test.h" int div(int a,int b) { return a / b; } /*****test.h*****/ #ifndef __TEST_H_ #define __TEST_H_ int add(int a,int b); int sub(int a,int b); int div(int a,int b); #endif 2) 编译生成目标文件gcc -c *.c *.c表示所有以.c结尾的文件,也即所有的源文件。执行完该命令,会发现 second 目录中多了三个目标文件,分别是 add.o、sub.o div.o。 3)把所有目标文件打包成静态库文件: ar rcs libtest.a *.o *.o表示所有以.o结尾的文件,也即所有的目标文件。执行完该命令,发现 test 目录中多了一个静态库文件 libtest.a。 4)创建新的目录结构:在second目录下创建math目录,在math下创建include, lib, src三个目录,并将test.h移动到include下: 在src目录下创建一个新的测试文件main.c,在 main.c 中,可以像下面这样使用 libtest.a 中的函数:: /*****main.c*****/ #include <stdio.h> #include "test.h" //必须引入头文件 int main(void) { int m, n; printf("Input two numbers: "); scanf("%d %d", &m, &n); printf("%d+%d=%d\n", m, n, add(m, n)); printf("%d-%d=%d\n", m, n, sub(m, n)); printf("%d÷%d=%d\n", m, n, div(m, n)); return 0; } 在编译 main.c 的时候,我们需要使用-I(大写的字母i)选项指明头文件的包含路径,使用-L选项指明静态库的包含路径,使用-l(小写字母L)选项指明静态库的名字。所以,main.c 的完整编译命令为: gcc src/main.c -I include/ -L lib/ -l test -o math.outcd 注意,使用-l选项指明静态库的名字时,既不需要lib前缀,也不需要.a后缀,只能写 test,GCC 会自动加上前缀后缀。 打开 math 目录,发现多了一个 math.out 可执行文件,使用./math.out命令就可以运行 math.out 进行数学计算。3. GCC 生成使用动态链接库 1)从文件生成动态库 从单个源文件生成动态链接库: $ gcc -fPIC -shared xxx.c -o libxxx.so 从目标文件生成动态链接库: $ gcc -fPIC -c xxx.c -o xxx.o $ gcc -shared xxx.c -o libxxx.so 从多个文件生成动态库: gcc -fPIC -shared xxx1.c xxx2.c xxx3.c -o libxxx.so 或:gcc -fPIC -shared xxx1.o xxx2.o xxx3.o -o libxxx.so 2)接上面第2个实例,首先已经编译生成的目标文件不能再用,因为不是按照动态链接方式生成的,如果需要就还需要再次重新编译目标文件gcc -fPIC -c add.c -o add.o 3)在此我们直接用源文件来重新编译直接生成动态链接库文件gcc -fPIC -shared add.c sub.c div.c -o libtest.so 4)使用动态链接库: 重新对测试程序main.c编译,这次采用动态链接库gcc src/main.c lib/libtest.so -o math2 生成后执行math2: 根据给的资料帮我给出执行代码
03-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值