In life, as in whist, hope nothing from the way card may be dealt to you. Play the card, whatever they be, to the best of your skill.-------人生如牌戏,别希望可以拿到什么样的牌。 不管拿到什么牌,用尽你的技巧来打好牌
文章目录
1,回顾知识及准备工作
小黑在之前写了关于编译过程 以及 静态库与动态库的区别 的博客,需要回顾的码友可以移步:
https://blog.csdn.net/weixin_46027505/article/details/105222904
https://blog.csdn.net/weixin_46027505/article/details/105223091
在制作库之前我们先建下面的目录结构:
- 第一个文件夹用来生成动态库
- 第二个文件夹用来生成静态库
- 第三个文件夹用来模拟我们日常调用库,其中lib用来存放生成好的静态库和动态库
下面给出add.c, head.c, sub.c 的代码:
add.c
int add(int a, int b)
{
return a +b;
}
head.h
#ifndef _HEAD_H_
#define _HEAD_H_
extern int add(int a,int b);
extern int sub(int a,int b);
#endif
sub.c
int sub(int a, int b)
{
return a - b;
}
然后我们在xuxiaohei下创建main.c来调用函数sub和add
#include<stdio.h>
#include "head.h"
int main(void)
{
printf("sum = %d\n",add(5,3));
printf("sub = %d\n",sub(5,3));
return 0;
}
2,静态库
2.1 静态库的生成
- 我们使用
gcc -c add.c
gcc -c sub.c
ar -crs libmystaticku.a add.o sub.o
- 生成静态库
- 然后将head.h和静态库复制到lib下
2.2 编译过程中静态库的使用
- gcc main.c -o myapp -I ./lib -lmystatic -L ./lib -static
- 其中第一个是大写的 i ,后面是头文件路径
- -lmystatic 是小写的L + 去掉lib和.a剩下的
- -L 后面跟库所在路径
2.2 运行程序时静态库的使用
因为静态库在静态链接库(静态编译)的时候,已经加载进myapp,所以可以直接执行,而后面的动态库就要复杂一些。
- 然后查看静态库大小和信息,可以后面与动态库比较
如果想要可执行文件 myapp 更小,可以
strip myapp
2,动态库
为了不混淆,我们将上面的myapp删除,然后用动态链接重新生成myapp
2.1 动态库的生成
gcc -fpic -shared add.c sub.c -o libmyshared.so
- 然后复制到xuxiaohei的lib下
2.2 编译过程中动态库的使用
这里和静态库一样,只是少了-static
2.3 运行程序时动态库的使用
出现问题
这是因为程序运行时没有找到动态链接库造成的。程序编译时链接动态库和运行时使用动态链接库的概念是不同的,在运行时,程序链接的动态链接库需要在系统目录下才行。
Linux下在运行程序时,会默认到 /lib、/lib64、/usr/lib以及LD_LIBRARY_PATH环境变量指定的路径下查找所需的动态库下查 找所需的动态库文件,如果没有则抛错。而这时libmycshared.so并不在系统库路径下,所以会出错
可以使用
ldd myapp查看具体错误
解决方案
方法一:
在linux下最方便的解决方案是拷贝libshared.so到绝对目录 /lib 下, 但是,要是超级用户才可以,因此要使用sudo。就可以生成可执行程序了
方法二:
将动态链接库的目录放到程序搜索路径中,可以将库的路径加到环境变量LD_LIBRARY_PATH中实现:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/xuxiaohei/test/xuxiaohei/lib
执行此命令后也可以生成可执行程序