生成静态库
若当前已有以下.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 更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 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链接库
-
/*
-
* max.c
-
*
-
* Created on: 2016年7月24日
-
* Author: Andy_Cong
-
*/
-
/*生成libmax.so链接库*/
-
/*
-
* # -shared 为链接库 让编译器知道是要编译一个共享库
-
* # -fPIC(Position Independent Code) 编译生成代码与位置无关
-
*/
-
int max(int a,int b)
-
{
-
return a>b?a:b;
-
}
-
/*
-
* gcc -Wall -g -fPIC -c max.c -o max.o
-
* gcc -shared max.o -o libmax.so
-
* -g -Wall 供调试使用,不是必须的
-
*/
编译结果:生成libmax.so
2、使用链接库,需要包含头文件(很正常,我们平时使用C库函数也需要包含相关头文件)
max.h头文件如下
-
/*
-
* max.h
-
*
-
* Created on: 2016年7月24日
-
* Author: Andy_Cong
-
*/
-
#ifndef MAX_H_
-
#define MAX_H_
-
int max(int a,int b);
-
#endif /* MAX_H_ */
测试函数main.c如下
-
/*
-
* main.c
-
*
-
* Created on: 2016年7月24日
-
* Author: Andy_Cong
-
*/
-
#include<stdio.h>
-
#include"max.h"
-
int main(void)
-
{
-
printf("call max function results is: %d\n",max(1,1));
-
return 0;
-
}
-
/* 使用libmax.so库
-
* gcc -o main main.c -L. -lmax
-
*
-
*-L.: 在当前路径下寻找.so文件
-
*-lmax: 要链接这个libmax.so文件
-
*
-
* */
运行结果:生成可执行程序main(成功了)
3、使用C++编译使用C语言提供的链接库, 编译链接出错(下面只是简单将main.c 改为main.cpp)
怎么办呢??
libmax这个库仅适合C使用,C++并不适合,如果想编译一个可以供C++使用。那么头文件(max.h)就需要改变,
需要额外增加一句:extern "C"
max.h(修改如下)
-
/*
-
* max.h
-
*
-
* Created on: 2016年7月24日
-
* Author: Andy_Cong
-
*/
-
#ifndef MAX_H_
-
#define MAX_H_
-
extern "C" // 这句话可理解为,告诉编译器,这个动态库(.so)是用C语言写的,
-
// 需要用C语言链接方式来链接这个库,这样就可以g++来编译了。
-
int max(int a,int b);
-
#endif /* MAX_H_ */
运行结果
这样就解决了。
4、但是这样有一个问题,难道每次编译都要改来改去,有没有同时适合C/C链接库的方法呢?
答案是有的,只需要改动头文件即可,使用条件编译
C++有一个宏:__cplusplus 当用g++编译的时候,就可以识别这个宏
-
/*
-
* max.h
-
*
-
* Created on: 2016年7月24日
-
* Author: Andy_Cong
-
*/
-
/*条件编译*/
-
#ifndef MAX_H_
-
#define MAX_H_
-
#ifdef __cplusplus
-
extern "C" //C++
-
{
-
#endif
-
int max(int a,int b);
-
#ifdef __cplusplus
-
}
-
#endif
-
#endif /* MAX_H_ */
然后发现写到最后,才知道,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