本文翻译自: How dynamic linking for modular libraries works on Linux
放到Ubuntu上试试行不行。
1.Linker
一个Linker是一种命令,将许多程序片段联系在一起,并且识别针对他们的内存分配。一个linker的功能包括:
(1) 集成程序的所有部分
(2) 恢复内存,以至于程序能运行在新的内存组织下。
(3) 解析符号引用
(4) 建立新的内存组织以至于所有的程序能组织在一起。
2.创建对象文件
首先,创建头文件mymath.h:
(关于如何创造头文件,参考:How to Create and Use Header Files in Linux C Programming)
#ifndef MYMATH_H
#define MYMATH_H
int add(int a, int b);
int sub(int a, int b);
int mult(int a, int b);
int divi(int a, int b);
#endif
接下来创造四个独立的.c文件,每一个.c文件中都定义一个函数:
// add.c
#include "mymath.h"
int add(int a, int b)
{
return (a+b);
}
//sub.c
#include "mymath.h"
int sub(int a, int b)
{
return (a - b);
}
//mult.c
#include "mymath.h"
int mult(int a, int b)
{
return (a*b);
}
//divi.c
#include "mymath.h"
int divi(int a, int b)
{
return (a/b);
}
使用下面的命令生成四个对象文件:
gcc -c add.c sub.c mult.c divi.c
3.创造共享的对象文件
在最终的可执行文件执行期间,动态链接库被连接。只有动态链接库的名字被放置在了最终的可执行文件中。实际的连接发生在运行过程中,此时可执行文件和动态链接库都被放在了主内存中。
除了可共享之外,动态库的另一个优点是它减小了最终可执行文件的大小。
用以下的命令创建动态链接库:
gcc -Wall -fPIC -c add.c sub.c mult.c divi.c
这条命令中的-fPIC告诉GCC生成位置独立的代码(PIC),-Wall选项使得编译器在编译出现问题时能发出警告。
接下来创造共享库libmymath.so:
gcc -shared -o libmymath.so add.o sub.o mult.o divi.o
现在你可以在你的自定义的代码中使用这个库,然后和它建立链接。
3.创造一个动态链接的可执行文件
假如我们要写一个数学计算的命令,先创造一个文件mathDemo.c:
#include <mymath.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x, y;
printf("Enter two numbers\n");
scanf("%d%d",&x,&y);
printf("\n%d + %d = %d", x, y, add(x, y));
printf("\n%d - %d = %d", x, y, sub(x, y));
printf("\n%d * %d = %d", x, y, mult(x, y));
if(y==0)
{
printf("\nDenominator is zero so can't perform division\n");
exit(0);
}
else
{
printf("\n%d / %d = %d\n", x, y, divi(x, y));
return 0;
}
}
请注意,第一行是一个include语句,它通过名称引用您自己的libmymath库。
接下来使用这两个命令:
sudo cp libmymath.so /usr/lib64/
sudo ldconfig
(1) 第一个命令将 libmymath.so拷贝到了标准的系统文件路径(这里作者的是/usr/lib64,但不同的计算机下安装的不同的Linux系统,情况可能不同,这位作者用的是Red Hat,而我用的是Ubuntu,我的这条命令就换成了/usr/lib)。
(2) 命令ldconfig创造了所需要的link,高速缓存到在标准库目录中找到的最新共享库。
4.编译应用
从你之前的应用源代码创建一个对象文件,名为mathDemo.o:
gcc -I . -c mathDemo.c
选项-I告诉GCC在后面列出的目录中寻找头文件(在本例中是mymath.h)。在本例子中,您将指定当前目录,由单个点 (.) 表示。
创建一个可执行文件,使用-l选项按名称引用您的共享库:
gcc -o mathDynamic mathDemo.o -lmymath
gcc能够找到libmymath.so因为它存在于默认的系统库文件夹中,使用ldd验证使用的共享库:
ldd mathDynamic
输出结果:
现在用如下命令查看可执行文件的大小:
du ./mathDynamic
输出结果:
运行可执行文件:
./mathDynamic
成功!