动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。

1、动态库的编译

下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

//so_test.h:

#include
"stdio.h"
void
test_a();
void
test_b();
void
test_c();

//test_a.c:

#include
"so_test.h"
void
test_a()
{
 
printf("this is in test_a...\n");
}

//test_b.c:

#include
"so_test.h"
void
test_b()
{
 
printf("this is in test_b...\n");
}

//test_c.c:

#include
"so_test.h"
void
test_c()
{
 
printf("this is in test_c...\n");
}
将这几个文件编译成一个动态库:libtest.so

$ gcc
test_a.c test_b.c test_c.c -fPIC -shared -o
libtest.so

2、动态库的链接
在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。

test.c:

#include
"so_test.h"
int
main()
{
test_a();
test_b();
test_c();
return
0;
}
将test.c与动态库libtest.so链接生成执行文件test:

$ gcc
test.c -L. -ltest -o test
测试是否动态连接,如果列出libtest.so,那么应该是连接正常了

$ ldd
test
执行test,可以看到它是如何调用动态库中的函数的。

3、编译参数解析
最主要的是GCC命令行的一个选项:
-shared该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

-L.:表示要连接的库在当前目录中

-ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用
/sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。

4、注意

调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过
“-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改
LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

在linux下可以用export命令来设置这个值,在linux终端下输入:

export
LD_LIBRARY_PATH=/opt/au1200_rm/build_tools/bin: $LD_LIBRARY_PATH:
  
然后再输入:export
  
即会显示是否设置正确
  
export方式在重启后失效,所以也可以用
vim /etc/bashrc ,修改其中的LD_LIBRARY_PATH变量。   
例如:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/au1200_rm/build_tools/bin。

Linux下gcc编译生成动态链接库*.so文件并调用它【转载】的更多相关文章

  1. Linux下gcc编译生成动态链接库*.so文件并调用它 是转载的

    动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一 ...

  2. Linux下gcc编译生成动态链接库*.so文件并调用它

    动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一 ...

  3. Linux下gcc编译生成动态链接库*.so文件并调用它(注:执行Test程序后无需用export 命令指定.so库文件路径:方法在文中下方;)

    动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一 ...

  4. linux下gcc默认搜索头文件及库文件的路径

    一.头文件gcc 在编译时如何去寻找所需要的头文件:※所以header file的搜寻会从-I开始※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC ...

  5. linux 下C语言编程库文件处理与Makefile编写

    做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...

  6. Linux下的文件结构,及对应文件夹的作用

    Linux下的文件结构,及对应文件夹的作用 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基点,比 ...

  7. linux找不到动态链接库 .so文件的解决方法(转自:http://www.cnblogs.com/xudong-bupt/p/3698294.html)

    linux找不到动态链接库 .so文件的解决方法 如果使用自己手动生成的动态链接库.so文件,但是这个.so文件,没有加入库文件搜索路劲中,程序运行时可能会出现找不到动态链接库的情形. 可以通过ldd ...

  8. Linux下用rm删除的文件的恢复方法

    Linux下用rm删除的文件的恢复方法_Linux教程_Linux公社-Linux系统门户网站https://www.linuxidc.com/Linux/2008-08/14744.htm linu ...

  9. linux找不到动态链接库 .so文件的解决方法

    linux找不到动态链接库 .so文件的解决方法 如果使用自己手动生成的动态链接库.so文件,但是这个.so文件,没有加入库文件搜索路劲中,程序运行时可能会出现找不到动态链接库的情形. 可以通过ldd ...

随机推荐

  1. 关于FlagsAttribute

    最近在看C#本质论,有介绍FlagsAttribute的特性,看了下源码,发现只是一个简单的特性class和一个构造函数. 调试了一下.NET的源码,发现在console.writeline(***) ...

  2. PHP微信支付开发之扫描支付(模式二)后如何回调

    其实在写这篇文章的时候感觉自己已经落伍了,不过笔者在百度上搜索"微信支付开发之扫描支付(模式二)后如何回调"寻找答案时,发现依旧有很多朋友没有解决这个问题,所以就把自己的解决思路分 ...

  3. centos-php安装

    初学者自编文档,如有错误,请指出,具体命令就不阐述了,不明白 度娘吧! nginx我是编译安装在服务器上 和其他安装应该会有区别 安装路径路径:/usr/local/ 安装包存放位置:/home/ap ...

  4. H264所采用的指数格伦布熵编码算法原理及应用

    1 指数格伦布熵编码算法原理 1.1 无符号整数k阶指数格伦布算法编码过程: 1) 将数字以二进制形式写出,去掉最低的k个比特位,之后加1 2) 计算留下的比特数,将此数减一,即是需要增加的前导零个数 ...

  5. JavaScript里利用DOM获取宽高大全

    网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...

  6. foreach 循环的应用传值

    $arr=array(1,5,8,8,9);foreach ($arr as $key => $value) { //这里可以一边改外面$arr的值一边下一步循环 $value=++$value ...

  7. centos7,yum安装的redis用systemctl无法启动

    因为之前使用显示命令启动redis的,要使redis在后台运行就需要改redis.conf中的daemonize 为yes. 这次在centos7上也顺手改了为yes,然后使用systemctl启动, ...

  8. Linux命令学习-useradd和usermod

    1.useradd 创建用户的时候创建家目录 useradd luyun :创建用户luyun,系统会自动创建/home/luyun 目录,此目录便是luyun的家目录. useradd -d /ho ...

  9. js获取json的value

    getJson('age'); function getJson(key){ var jsonObj={"name":"cxr","age" ...

  10. Struts2 stracture