Linux 库

linux下静态链接库生成和使用

生成静态库

  若当前已有以下.o文件: obj1.o obj2.o

  则gcc指令如下:

    ~$ ar -rsv libtest.a obj1.o obj2.o

  ranlib指令:来对静态库的符号索引表进行更新

    ~$ ranlib libtest.a

  注:linux下生成静态库.a文件有一个命名规则,必须 lib 开头 .a 结尾, 即 libXX.a

 

使用静态库

 1.使用路径,如

  ~$ g++ test.o ./libtest.a -o test.out

  若还依赖其他目录下的库,则也用这种绝对路径方式链接,如

  ~$ g++ test.o ./libtest.a /usr/local/lib/libboost_thread.a -o test.out

  注:以上指令./libtest.a 和 /usr/local/lib/libboost_thread.a 都是使用路径指定要依赖的库文件,并指定链接的文件是.a(静态库)

 

 2.使用 -L 设置文件路径,-l 代表库名,例文件为 libtest.a 则参数为 -ltest

  ~$ g++ test.o -L./ -llog -L/usr/local/lib -lboost_thread -o test.out

  其中:-L./ 表示当前目录 -L/usr/local/lib表示 /usr/local/lib 目录

  但是:使用 -L -l 会带来一个问题,该方式不指定链接库类型,即静态or动态(.a or .so),且优先链接动态库

  这会带来一个问题:以上条指令为例, /usr/local/lib 下包含了boost的静态和动态库文件,当使用 -L/usr/local/lib -lboost_thread 时,链接可通过,可生成可执行文件,但是一执行就会出现提示  error while loading shared libraries: libboost_thread.so.1.49.0: cannot open shared object file: no such file or directory

  这是因为使用 -L/usr/local/lib -lboost_thread 时,优先链接了动态库,而执行时却发现 .so 文件不在,相当于windows下的dll机制, -L./ -llog 链接正常是因为编译器在./下没找到相关的 .so 文件,此时才去加载 .a 文件

  解决这个问题的办法:设法让可执行文件找到.so文件。也许你会把那个.so 文件拷贝到 可执行文件目录下,你会发现这是行不通的。linux里有一个环境变量叫 LD_LIBRARY_PATH, 可以理解为windows的 Path 环境变量,可在终端输入 echo $LD_LIBRARY_PATH 输出该变量值,我们只要设置该变量值到相应目录就可以解决找不.so 文件的问题了。 

  ~$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

  再执行文件,OK,问题解决。

 

  注: 在终端用 export 指令只是暂时改变 LD_LIBRARY_PATH 的值,重启之后该值又为空,

  靠谱方法为:在~/.bashrc 或者 ~/.bash_profile 中加入该 export 语句,前者在每次登陆和每次打开 shell 都读取一次,后者只在登陆时读取一次。习惯是加到 ~/.bashrc 中,在该文件的未尾可采用如下语句来使设置生效:

  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

  修改完后,记得关掉当前终端并重新打开一个新的终端,从而使上面的配置生效。

  export 后面的语句不能包含空格

  另外: ldd 指令  可以查看可执行文件对哪些动态库有依赖关系

Linux-(C/C++)动态链接库生成以及使用(libxxx.so)

2016年07月24日 17:29:54 YehChiTian 阅读数:29676 标签: LinuxCCgccg动态链接库so 更多

个人分类: LinuxC/C++

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33850438/article/details/52014399

linux静态库生成与使用:http://www.cnblogs.com/johnice/archive/2013/01/17/2864319.html

Linux中so文件为共享库,与windows下dll类似,不过实现要简单。

so可以供多个进程使用,不同进程调用同一个so文件,所使用so文件不同。

so文件源程序不需要main函数,有也不会被执行。

下面通过一个简单例子,来学习.so文件的制作跟使用(前提已经配置好环境)、

主要了解学习用C语言编译一个动态链接库,如何使用这个库

1、通过简单max函数,生成一个libmax.so链接库

 

 
  1. /*

  2. * max.c

  3. *

  4. * Created on: 2016年7月24日

  5. * Author: Andy_Cong

  6. */

  7.  
  8. /*生成libmax.so链接库*/

  9. /*

  10. * # -shared 为链接库 让编译器知道是要编译一个共享库

  11. * # -fPIC(Position Independent Code) 编译生成代码与位置无关

  12. */

  13. int max(int a,int b)

  14. {

  15. return a>b?a:b;

  16. }

  17. /*

  18. * gcc -Wall -g -fPIC -c max.c -o max.o

  19. * gcc -shared max.o -o libmax.so

  20. * -g -Wall 供调试使用,不是必须的

  21. */

  22.  

 

编译结果:生成libmax.so

 

2、使用链接库,需要包含头文件(很正常,我们平时使用C库函数也需要包含相关头文件)

max.h头文件如下

 

 
  1. /*

  2. * max.h

  3. *

  4. * Created on: 2016年7月24日

  5. * Author: Andy_Cong

  6. */

  7.  
  8. #ifndef MAX_H_

  9. #define MAX_H_

  10.  
  11. int max(int a,int b);

  12.  
  13.  
  14. #endif /* MAX_H_ */

  15.  


测试函数main.c如下

 

 

 
  1. /*

  2. * main.c

  3. *

  4. * Created on: 2016年7月24日

  5. * Author: Andy_Cong

  6. */

  7. #include<stdio.h>

  8. #include"max.h"

  9. int main(void)

  10. {

  11. printf("call max function results is: %d\n",max(1,1));

  12. return 0;

  13. }

  14. /* 使用libmax.so库

  15. * gcc -o main main.c -L. -lmax

  16. *

  17. *-L.: 在当前路径下寻找.so文件

  18. *-lmax: 要链接这个libmax.so文件

  19. *

  20. * */

  21.  
  22.  

 

 

运行结果:生成可执行程序main(成功了)

 

3、使用C++编译使用C语言提供的链接库, 编译链接出错(下面只是简单将main.c 改为main.cpp)

 

怎么办呢??

 

libmax这个库仅适合C使用,C++并不适合,如果想编译一个可以供C++使用。那么头文件(max.h)就需要改变,

需要额外增加一句:extern "C"

max.h(修改如下)

微笑

 
  1. /*

  2. * max.h

  3. *

  4. * Created on: 2016年7月24日

  5. * Author: Andy_Cong

  6. */

  7.  
  8. #ifndef MAX_H_

  9. #define MAX_H_

  10.  
  11. extern "C" // 这句话可理解为,告诉编译器,这个动态库(.so)是用C语言写的,

  12. // 需要用C语言链接方式来链接这个库,这样就可以g++来编译了。

  13. int max(int a,int b);

  14.  
  15. #endif /* MAX_H_ */

  16.  


运行结果

 

 

这样就解决了。

4、但是这样有一个问题,难道每次编译都要改来改去,有没有同时适合C/C链接库的方法呢?

答案是有的,只需要改动头文件即可,使用条件编译

C++有一个宏:__cplusplus   当用g++编译的时候,就可以识别这个宏

 

 

 
  1. /*

  2. * max.h

  3. *

  4. * Created on: 2016年7月24日

  5. * Author: Andy_Cong

  6. */

  7.  
  8. /*条件编译*/

  9. #ifndef MAX_H_

  10. #define MAX_H_

  11.  
  12. #ifdef __cplusplus

  13. extern "C" //C++

  14. {

  15. #endif

  16. int max(int a,int b);

  17. #ifdef __cplusplus

  18. }

  19. #endif

  20.  
  21. #endif /* MAX_H_ */

  22.  

 

 

然后发现写到最后,才知道,main.c调用max函数时,居然使用同一个参数,好傻, 给自己狠狠一巴掌。

 

配置环境:http://www.tuicool.com/articles/6JVR3m

详细可以在大神博客学习: http://blog.csdn.net/sunboy_2050/article/details/7346146

 

 

本来原文来自:http://blog.csdn.net/qq_33850438/article/details/52014399

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值