当前位置: 首页 > 编程日记 > 正文

【转载】linux静态链接库与动态链接库的区别及动态库的创建


这篇文章对于动态库的概念及使用介绍的很不错,故收藏了。

一、引言

通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“libxxx.a”的形式。

其实,我们也可以把对一些库函数的链接载入推迟到程序运行的时期(runtime)。这就是如雷贯耳的动态链接库(dynamic link library)技术。

二、动态链接库的特点与优势

首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:

1. 可以实现进程之间的资源共享。

什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统内存资源。C的标准库就是动态链接库,也就是说系统中所有运行的程序共享着同一个C标准库的代码段。

2. 将一些程序升级变得简单。用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows 就是一个很好的例子。

3. 甚至可以真正坐到链接载入完全由程序员在程序代码中控制。

程序员在编写程序的时候,可以明确的指明什么时候或者什么情况下,链接载入哪个动态链接库函数。你可以有一个相当大的软件,但每次运行的时候,由于不同的操作需求,只有一小部分程序被载入内存。所有的函数本着“有需求才调入”的原则,于是大大节省了系统资源。比如现在的软件通常都能打开若干种不同类型的文件,这些读写操作通常都用动态链接库来实现。在一次运行当中,一般只有一种类型的文件将会被打开。所以直到程序知道文件的类型以后再载入相应的读写函数,而不是一开始就将所有的读写函数都载入,然后才发觉在整个程序中根本没有用到它们。

三、动态链接库的创建

由于动态链接库函数的共享特性,它们不会被拷贝到可执行文件中。在编译的时候,编译器只会做一些函数名之类的检查。在程序运行的时候,被调用的动态链接库 函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。因此,这些代码必须实用相对地址,而不是绝对地址。在编译的时候,我们需要告诉编译器, 这些对象文件是用来做动态链接库的,所以要用地址不无关代码(Position Independent Code (PIC))。

对gcc编译器,只需添加上 -fPIC 标签,如:

gcc -fPIC -c file1.c
gcc -fPIC -c file2.c
gcc -shared libxxx.so file1.o file2.o

注意到最后一行,-shared 标签告诉编译器这是要建立动态链接库。这与静态链接库的建立很不一样,后者用的是 ar 命令。也注意到,动态链接库的名字形式为 “libxxx.so” 后缀名为 “.so”

四、动态链接库的使用

使用动态链接库,首先需要在编译期间让编译器检查一些语法与定义。

这与静态库的实用基本一样,用的是 -Lpath 和 -lxxx 标签。如:

gcc file1.o file2.o -Lpath -lxxx -o program.exe

编译器会先在path文件夹下搜索libxxx.so文件,如果没有找到,继续搜索libxxx.a(静态库)。

在程序运行期间,也需要告诉系统去哪里找你的动态链接库文件。在UNIX下是通过定义名为 LD_LIBRARY_PATH 的环境变量来实现的。只需将path赋值给此变量即可。csh 命令为:

setenv LD_LIBRARY_PATH your/full/path/to/dll

一切安排妥当后,你可以用 ldd 命令检查是否连接正常。

ldd program.exe


动态链接库*.so的编译与使用

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

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

so_test.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_a.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

l 执行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文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

相关文章:

买不到回家的票,都是“抢票加速包”惹的祸?

作者 | 屠敏来源 | CSDN(ID:CSDNNews)距离国家法定春节假日不足一个月,且首批除夕票已于近日正式开售。但万万没想到,当人、钱、手机、PC、iPad 万事俱备之际,东风刮得太快,眼巴巴盯着将于整点开…

HTSRealistic missions 10:Holy Word High School

这到题说实在的挺难。。。首先进入页面,进去后查看源代码发现有个空图片,图片是个链接,链接到staff.php。点击进入要求用户名密码,尝试注入,无效在来至主页,有个staff list的链接,点进去&#x…

Makefile的东西

宏定义: 1. Makefile中直接定义宏 OBJECTSfilea.o fileb.o filec.o #定义宏 Zfiled.oprog: $(OBJECTS) #引用宏cc $(OBJECTS) -o prog #我的机子环境中需要4个tab键prog1: $Z #引用宏,单个字符无需加园括号cc $Z -o prog12. 在make命令之后带有新的宏定…

TensorFlow 2.0开发者预览版发布

整理 | Jane出品 | AI科技大本营从去年 8 月 Google 公开发布消息正在研发 TensorFlow 2.0 ,让我们在 12 月 提前看到了一些 高级 API 的变化,今天我们终于等来了“tf-nightly-2.0”,一个 TensorFlow 2.0 开发者预览版。在今天 Wicke 的邮件中…

DOCKER OVERLAY NETWORK consul 注册

下载 consul 二进制包并启动 wget https://releases.hashicorp.com/consul/0.9.2/consul_0.9.2_linux_amd64.zip unzip consul_0.9.2_linux_amd64.zip mv consul /usr/bin/consul && chmod x /usr/bin/consul nohup consul agent -server -bootstrap -ui -data-dir /va…

怎么写shell脚本才能不耍流氓?

1、不记录日志的 SHELL 脚本就是耍流氓! 我们经常在工作中会遇到一个苦恼的事情,一个 Shell 脚本到底干了什么,什么时候开始执行,什么时候结束的。尤其是数据库备份,我们想知道我们的 MySQL 数据库备份时间。所以给脚本…

透过腾讯张潼离职事件,看AI研究院如何才算成功?

作者 | 洪亮劼编辑 | 琥珀【AI科技大本营导读】近日腾讯 AI Lab 第一负责人张潼博士的离职事件,让不少圈内人士对企业 AI 研究院/实验室的定位、落地能力等问题进行了深刻思考和讨论。据最新消息,张潼未来将回到学界,继续 AI 领域的学术研究&…

java vs .net

... vs paramsjavaprivatestaticintsumUp(int... values) { intsum 0; for(inti 0; i < values.length; i) { sum values[i]; } returnsum; } .netparams 关键字在方法成员的参数列表中使用&#xff0c;为该方法提供了参数个数可变的能力它在只能出现一次并…

#QCon# Devops

今天参加了QCon2011 杭州。听了百度项目管理部的乔梁关于“Devops”的分享。比如如下&#xff1a; continuous integration —— Dev &#xff0c; QA agile —— Business&#xff0c;Dev&#xff0c;QA devops —— Dev&#xff0c;QA&#xff0c;Ops Devops Culture Too…

雷军的100亿计划:不服就干,生死看淡

图片来自小米官网整理 | 琥珀出品 | AI 科技大本营1 月 10 日&#xff0c;红米品牌正式独立。11 日&#xff0c;雷军在小米年会上宣布&#xff0c;2019 年&#xff0c;小米将正式启动“手机AIoT”双引擎战略&#xff0c;作为小米未来五年的核心战略。同时&#xff0c;未来 5 年…

cppcheck源码学习(一)

今天整理了下cppcheck的源码结构&#xff0c;为什么通过写一个个子文件就能够扩展cppcheck的功能呢&#xff1f; 看了下代码&#xff0c;并通过简化代码&#xff0c;略懂一二了。 首先我们定义一个基类test.h&#xff0c;只定义一个头文件足够&#xff1a; #ifndef TESTH #defi…

产品与技术优势发威 用友U9截击SAP ORACLE

随着金融危机的全面爆发&#xff0c;实体经济的冬天也随之而来。也正是金融危机&#xff0c;使得多年以来一直高调占据媒体头条的管理软件厂商们略显低迷&#xff0c;使一直剑拔弩张的中国管理软件市场&#xff0c;进而升级为一场“血腥四溅的肉搏”。<?xml:namespace pref…

oracle中的exists 和 not exists 用法详解

from&#xff1a;http://blog.sina.com.cn/s/blog_601d1ce30100cyrb.htmloracle中的exists 和 not exists 用法详解 (2009-05-14 16:58:18) 有两个简单例子&#xff0c;以说明 “exists”和“in”的效率问题1) select * from T1 where exists(select 1 from T2 where T1.aT2.a)…

清华北大“世界排名断崖式下跌”?

作者 | 琥珀出品 | AI 科技大本营为什么人们疯狂地爱着排名&#xff1f;基本每过一年公布的全球大学排行榜&#xff0c;都会吸引不少的利益相关方甚至吃瓜群众的集体关注。每每此时&#xff0c;网络上泛滥着的却是眼花缭乱、无法令人辨别真假的数字依据&#xff0c;甚至是“专家…

#Qcon# 分享

明天被领导要求分享Qcon体会&#xff0c;实在是件不怎么容易的事情。Qcon这样的企业开发大会&#xff0c;很多东西必须要实际应用过才能深有体会&#xff0c;泛泛的谈似乎又觉得乏味。好吧&#xff0c;泛一下就泛一下吧&#xff0c;总比废话要强(上一句是我认为的废话)。 第二天…

判断一个数为多少位 比如 3 是 1位 102 是3位。

12345678910111213141516//判断一个数为多少位 比如 3 是 1位 102 是3位。#include <iostream>using namespace std; int main() {int a; cout<<"input a num"<<endl; cin>>a; int t1; for(int i10;i<10000000;i*10,t) if(a<i) brea…

完成CitrixVDI架构了解及部署测试

很是不错&#xff0c;经过近两周时间对CitrixVDI架构的学习&#xff0c;有了初步的了解和认识&#xff0c;同时&#xff0c;也在家中完成了整个体系的部署实验。由于公司正在使用着VMware的VDI(Viewe3.0)&#xff0c;又在测试CitrixVDI&#xff0c;使两者终于有了直接的对比&am…

keepalive

高可用解决方案&#xff1a; heartbeat corosync cman keepalived 前面我们讲解了&#xff0c;LVS&#xff08;负载均衡器&#xff09;、Heartbeat、Corosync、Pacemaker、Web高可用集群、MySQL高可用集群、DRDB、iscsi、gfs2、cLVM等&#xff0c;唯一没有讲解的就是LVS可用&a…

普元王葱权:数字化时代需要新一代的大数据应用平台架构

记者 | 杨丽出品 | AI 科技大本营&#xff08;rgznai100&#xff09;2018 年 12 月 6 日&#xff0c;北京新云南皇冠假日酒店&#xff0c;由中国计算机学会主办&#xff0c;CCF 大数据专家委员会承办&#xff0c;CSDN、中科天玑数据科技股份有限公司协办的 2018 中国大数据技术…

Agile DSL Development in Ruby 笔记

pdf见&#xff1a;http://obiefernandez.com/presentations/obie_fernandez-agile_dsl_development_in_ruby.pdf 1. What is DSL ——designed for a specific domain ——captures jargon in executable form ——can be internal or external 2. How to design Ruby DSL (…

人生的出口。在哪

清晨&#xff0c;雨停了。到处都是滴滴答答的雨滴声。似乎这场空洞漫长的过程一直在延续着。也不知道是为什么。在下完雨之后。自己的心情会特别的低落沉重。似乎经历了一场浩劫。没有太多的言语可以去描述。只有自己内心乏味的明白那些含义深刻的东西。约了好友。我迟到了十多…

zabbix专题:第十一章 zabbix之SNMP方式监控

&#xff08;SNMP基本都是监控网络设备&#xff0c;本文介绍点理论知识&#xff09; 概述 如果我们需要监控打印机、路由器、UPS等设备,肯定不能使用zabbix agentd,因为他们不能安装软件的,还好他们一般都支持SNMP协议,这样我可以使用SNMP来监控他们.如果你希望使用SNMP agent来…

Some Rules from wrting your own dsl with ruby

来自&#xff1a;http://blog.nofail.de/2010/02/writing-your-own-dsl-with-ruby/ Some Rules from wrting your own dsl with ruby 1. let the user choose how to use it all implemented methods return the object instance itself,so one can chain method calls for con…

免费报名 | 微软全双工语音对话以及在智能硬件上的应用

微软小冰第六代发布会上正式宣布上线全新的共感模型&#xff0c;同时也开始公测一种融合了文本、全双工语音与实时视觉的新感官。这项新技术可以实时预测人类即将说出的内容&#xff0c;实时生成回应&#xff0c;并控制对话节奏&#xff0c;从而使长程语音交互成为可能。而采用…

文件服务器迁移

不论大小&#xff0c;几乎每个公司都有自己的文件服务器&#xff0c;或者简单点的共享文件夹。随着数据的爆炸式增长&#xff0c;以及天长日久累积下来&#xff0c;数据量往往在一年两之后就超出服务器的容量。要解决这个问题&#xff0c;首先当然是做好数据管理&#xff0c;用…

Windows脚本初探之PowerShell流程控制if

Windows Powershell中if语句为可以为一下三种形式&#xff0c;只用表达式为True时才执行相应花括号中的命令语句/块&#xff1a; 示例1&#xff1a; 1234if (表达式1) { 命令语句/块1 } 示例2&#xff1a; 12345678if (表达式1) { 命令语句/块1 } else{ 命令语句/块2 } 示例3&a…

“万人迷”小冰背后的AI故事

作者 | Jane出品 | AI科技大本营从 2014 年的夏天小冰出现在我们的视野到今天&#xff0c;谈到小冰&#xff0c;你的第一印象是什么&#xff1f;一款可爱、萌萌哒的聊天机器人&#xff1f;一款随时在你身边&#xff0c;可以帮你做一些场景任务的语音助手&#xff1f;如果说&…

开放式Android联盟成立

在Google采取行动反对CyanogenMod项目的几天之后&#xff0c;提供了定制的Android固件。一组Android开发者成立了开发式Android联盟。根据项目的网站介绍&#xff0c;这个联盟是‘pro-Android’而不是‘anti-Google’。他们的目的取代封闭的源代码&#xff0c;专有的应用程序包…

QQ卖手办,用AI分析用户评论

作者 | 徐汉彬指导 | 宋彦编辑 | Jane出品 | AI科技大本营徐汉彬&#xff0c;腾讯鹅漫前台研发团队 Leader&#xff0c;T3-3 级工程师&#xff0c;负责鹅漫U品和 AMS 平台&#xff08;高峰期 PV 超过 13 亿&#xff09;的研发工作&#xff0c;在 Web 研发、活动运营服务领域有丰…

使用svn时碰到的一个的问题

做技术的人&#xff0c;需要有完美主义&#xff0c;很多问题&#xff0c;如果当时不能彻底解决&#xff0c;往往会留下更大的麻烦。这个字符编码的问题&#xff0c;当时碰到的时候没有主义&#xff0c;以后遇到的时候也是抱着躲避的鸵鸟主义的态度&#xff0c;今天认真对待了一…