我们在写c语言的时候,经常会去包含一个.h的头文件,这个头文件就是库文件,比如<stdio.h>,<stdlib.h>这些都是标准的头文件,一般放在/usr/include,也就是说,从这个目录中我们可以找到这个头文件,然后调用它的库里面的方法,当然这些库是gcc帮助我们自动链接的,那么这里就延伸出了一个问题,不在标准库里面的头文件,我们怎么引用,也就是我们自己的头文件怎么引用?,

那么用一张图先来说明一下,介绍一下头文件的用法与作用:

比如我们做一个没有引入.h文件的库:

add.c

minus.c

 

先把这两个文件函数做成一个动态库:

 

 

然后移动到相应我们存放自己库文件位置:

然后demo1.c测试一把,注意我们没有引入头文件

 运行

所以,头文件是不是可以不加,但是其实不然 ,头文件可以帮我们定义数据类型,规范函数接口,就当相于是一个手册参考

OK,话不多说,上代码:

上面就是我在/home/pxx/include下面放的我自己的头文件,在/home/pxx/lib放的我的库文件,这是一个静态库,至于静态库怎么来制作,我们后面再来说。 

然后我在/home/pxx/c里面放的我的测试文件demo2.c

demo2.c:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include "add.h"
  4 
  5 int main()
  6 {
  7         int res1 = add(1,2);
  8         int res2 = sum(2,3);
  9         printf("%d  %d\n",res1,res2);
 10         return 0;
 11 }

 上面就是引用我们add.h的头文件,这个文件默认会去找当前目录有没有这个头文件,没有就去找我们指定的地方,然后去调用实现它的库文件。

下面我们来编译一下,首先我们看第一个情况,链接了头文件没有链接库文件:

 再来看一个情况,我们链接了库,但是没链接头:

 下面看一个标准链接:

 下面来具体说一下静态库与动态库:

一张图说明什么是静态库与动态库:

下面说一下静态库与动态库的制作方法:

我们在使用库的时候,往往是与头文件一起使用的,头文件定义函数,库文件实现函数。另外就是,我们一般用动态链接库比较多,节约内存嘛,然后就是整体升级也方便。但是如果你要考虑程序的移植性,就考虑用静态库吧。

话不多说,上代码。

静态库太简单,不说了,这里重点说一下动态库:

add.h:(/home/pxx/include)

  1 #ifndef  _ADD_H_
  2 #define  _ADD_H_
  3 
  4 
  5 int add(int num1,int num2);
  6  
  7 #endif

 add.c:(/home/pxx/include)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 int add(int num1,int num2)
  5 {
  6         return num1 + num2;
  7 }
~             

然后编译成.o文件用来制作动态库:

 

然后我们在来制作成动态库:

现在可以把这个共享库放到/home/pxx/lib里面:

 现在去到我们/home/pxx/c里面:

demo3.c:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include "add.h"
  4 
  5 
  6 int main()
  7 {
  8         int res = add(1,2);
  9         printf("%d\n",res);
 10         return 0;
 11 }

现在我们来链接一下共享库,调用这个函数:

上面很明显的有一个出现一个问题,这个问题的出现也说明了一个问题,就是我们在gcc链接库的时候没有报这个错误,运行程序的时候才报错,说明,动态库就是在链接的时候运行的。

我们来分析一下为什么提示找不到这个文件或者目录呢

ldd->可以查看可执行文件的可依赖的库文件

很明显libadd1.so找不到,那么下面就要延伸一个文件路径查找问题:

我们不是在编译程序的时候加入了-L/home/pxx/lib这个库文件位置吗,为什么还会提醒我们找不到。

那是因为库文件没有加载到环境变量中,因此程序在加载库的时候,就无法找到它的绝对路径,然后就无法加载到内存中。那么如何把这个库加入到环境变量中,下面给又得延伸一个可执行程序路径查找问题,一般来说可执行程序是elf格式的,那么我们就必须知道elf格式文件路径是怎么查找的。先来看一下dmeo3可执行文件是否是elf格式:

上面很明显看到demo3是elf格式的文件,那么现在说一下elf格式文件路径查找:

那么我们只要在上面任何一个设置好共享库的位置,就肯定可以让我们的共享库加载到内存中

那么说一下解决办法:

我们用推荐的方法:

注意.bashrc是一个隐藏文件 

 

再来ldd一下执行文件,看看我们需要的库是否都找到了

 然后我们运行

我们也可以去测试一下其他方法都可以找到动态库的问题。好了,就说到这吧。 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐