Linux下关于动态库的说明 | 编译以及调用

2017-07-23 学习C++动态库的基本知识 网络总结知识点


  • 动态库的概念 ​ 日常编程中,常有一些函数不需要进行编译或者可以在多个文件中使用(如数据库输入/输出操作或屏幕控制等标准任务函数)。可以事先对这些函数进行编译,然后将它们放置在一些特殊的目标代码文件中,这些目标代码文件就称为库。库文件中的函数可以通过连接程序与应用程序进行链接,这样就不必在每次开发程序时都对这些通用的函数进行编译了。

​ 动态库是一种在已经编译完毕的程序开始启动运行时,才被加载来调用其中函数的库。其加载方式与静态库截然不同。


  • 动态库的命名 ​ Linux下,动态库通常以.so(shareobject)结尾。(通常/lib和/usr/lib等目录下存在大量系统提供的以.so结尾的动态库文件) ​ Windows下,动态库常以.dll结尾。(通常C:\windows\System32等目录下存在大量系统提供的以.dll结尾的动态库文件)

  • 动态库和静态库的区别 ​ 静态库是指编译连接时,把库文件的代码全部加入到可执行文件中,所以生成的文件较大,但运行时,就不再需要库文件了。即,程序与静态库编译链接后,即使删除静态库文件,程序也可正常执行。 ​ 动态库正好相反,在编译链接时,没有把库文件的代码加入到可执行文件中,所以生成的文件较小,但运行时,仍需要加载库文件。即,程序只在执行启动时才加载动态库,如果删除动态库文件,程序将会因为无法读取动态库而产生异常。

  • 动态库的编译 下面我们来举一个栗子: 三个文件生成一个libdemo.so库文件 so_demo.hdemo_say.cppdemo_print.cpp so_demo.h源码 #include <iostream> using namespace std; void sayHello(); void printInfo(); demo_say.cpp源码 #include "so_demo.h" void sayHello(){ cout<<"hello AlicFeng"<<endl; } demo_print.cpp源码 #include "so_demo.h" void printInfo(){ cout<<"this is message"<<endl; } 通过g++命令编译生成libdemo.so动态库文件 ➜ g++ demo_say.cpp demo_print.cpp -fPIC -shared -o libdemo.so # 查看一下文件,如意生成一个libdemo.so文件 ➜ ls demo_print.cpp demo_say.cpp so_demo.h test.cpp

  • 动态库的使用 我们编写一个C++程序来使用刚刚生成的动态库文件 test.cpp源码 #include "so_demo.h" int main(){ sayHello(); printInfo(); return 0; } 编译test.cpp源码 # 先将生成的libdemo.so文件放进系统默认的依赖库目录中 ➜ sudo cp libdemo.so /usr/lib # 编译 ➜ g++ test.cpp -L/usr/lib -ldemo -o test # 使用 it is okay ➜ ./test hello AlicFeng this is message

  • **编译参数解析 -shared :该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件 -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。 -L.:表示要连接的库在当前目录中 -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称 LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。 当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
  • 注意 ​ 调用动态库的时候有几个问题会经常碰到,明明已经将库的头文件所在目录 通过 “-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。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

Windows 2008 R2 Server Core .NET环境配置

.NET Framework的部分功能在2008 R2 Server Core得到支持,包括:.NET 2/3/3.5的子集和ASP.NET。另外,PowerS...

1886
来自专栏xingoo, 一个梦想做发明家的程序员

【翻译】Tomcat 6.0 部署与发布

本篇参考Tomcat官方文档:《First Webapp》翻译,并结合自己的开发经验介绍关于tomcat部署以及发布的相关内容。 1 目录结构   在to...

1879
来自专栏老马寒门IT

08Vue.js快速入门-Vue综合实战项目

8.1. 前置知识学习 npm 学习 官方文档 推荐资料 npm入门 npm介绍 需要了解的知识点 package.json 文件相关配置选项 ...

2987
来自专栏木宛城主

SharePoint自动化部署,利用SPSD工具包

目录 怎样使用SPSD 配置Environment XML文件 PowerShell激活Feature  上篇博客讲了利用PowerShell导出、导入AD...

1859
来自专栏猛牛哥的博客

nginx rewrite伪静态配置参数详解

1905
来自专栏weixuqin 的专栏

使用代理爬取微信文章

3407
来自专栏Java成神之路

Eclipse_debug异常_Source not found

在eclipse中,打了断点之后运行代码,出现debug异常:Source not found,如下图

602
来自专栏IMWeb前端团队

AS3程序员小福利--as3js介绍及FlashDevelop工程的配置

本文作者:IMWeb 黄龙 原文出处:IMWeb社区 未经同意,禁止转载 ? 什么是AS3JS? AS3JS是ActionScript 3.0到Jav...

1976
来自专栏信安之路

记一次审计 xiaocms 的过程

周末在家刚吃完晚饭,基友 DM 叫我一起来审计 xiaocms 系统,也不知道他是受到啥刺激了。正好,除了 Code Review 公司项目代码及框架代码,未审...

2060
来自专栏用户2442861的专栏

linux动态库和静态库

http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520101023104745738/

692

扫码关注云+社区