浅析C/C++ library
1 背景
原来跑的好好的进程,重启后没跑多少就挂掉了,奇怪了。经过跟踪,原来是加载了一个.so文件,于是决定学习一下library相关的东东,现在和大家分享一下。
2 分类
C/C++ library可分为三类:静态库(Static Libraries)、共享库(shared Libraries)和动态加载库(dynamically loaded DL libraries)。
静态库在程序编译时会被连接到可执行程序中,程序运行时将不再需要该静态库。
共享库在程序编译时并不会被连接到可执行程序中,而是在可执行程序启动时被载入内存的,因此在程序运行时还需要动态库存在。
动态加载库在可执行程序执行的任何时候可以被加载。 DL libraries aren't really a different kind of library format (both static and shared libraries can be used as DL libraries)。
3 Static Libraries
创建方法:
|
ar rcs libmy_library.a file1.o file2.o |
4 Shared Libraries
4.1 命名
soname: version number,由ldconfig -n $library_directory生成,程序加载依赖的名字,
library安装好之后,根据realname生成soname
realname: soname的基础上增加minor number和release number
linkername: 以so结尾,没有version number,也没有minor number和release number,
ldconfig对于开发程序时你要链接的library不做出任何假定,不会自动生成linkername
有如下的指向关系
soname -> realname
linkername -> realname
例子如下所示:
soname ----> /usr/lib/libreadline.so.3 -> /usr/lib/libreadline.so.3.0
realname ----> /usr/lib/libreadline.so.3.0
linkername ----> /usr/lib/libreadline.so -> /usr/lib/libreadline.so.3
所以一般的情况是
linkername -> soname -> realname
4.2 使用方法
当执行一个ELF文件的时候,program loader(/lib/ld-linux.so.X,程序加载器)寻找并加载ELF文件所需要的所有libraries,搜寻的目录在/etc/ld.so.conf当中指定。/etc/ld.so.preload 文件当中指示那些预加载的,优先级高于一般libraries的库,为了提高加载效率,不用每次执行一个程序都去搜索,便有了文件/etc/ld.so.cache,每次有新的libraries加入或者删除一些libraries,都应该运行ldconfig,更新文件/etc/ld.so.cache。
4.3 环境变量
4.3.1 LD_LIBRARY_PATH
LD_LIBRARY_PATH环境变量用于在程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径,注意,LD_LIBRARY_PATH中指定的路径会在系统默认路径之前进行查找。设置方法如下(其中,LIBDIR1和LIBDIR2为两个库目录):
export LD_LIBRARY_PATH=LIBDIR1:LIBDIR2:$LD_LIBRARY_PATH
4.3.2 LIBRARY_PATH
LIBRARY_PATH环境变量用于在程序编译期间查找动态链接库时指定查找共享库的路径,例如,指定gcc编译需要用到的动态链接库的目录。设置方法如下(其中,LIBDIR1和LIBDIR2为两个库目录):
export LIBRARY_PATH=LIBDIR1:LIBDIR2:$LIBRARY_PATH
4.3.3 LD_PRELOAD
这个变量的作用类似于/etc/ld.so.preload
4.3.4 LD_DEBUG=files/libs/bindings/versions/help
通过这个变量的设置会显示share library函数调用时候的更加详细信息
4.4 工具
4.4.1 动态链接库管理命令ldconfig
为了让动态链接库为系统所共享,还需运行动态链接库的管理命令--ldconfig.
ldconfig命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件.缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。
ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。
4.4.2 ldd
ldd,列出某个程序依赖的shared library,不要对某个不信任的程序进行ldd,因为ldd的工作方式是:首先,设置某个变量,LD_TRACE_LOADED_OBJECTS,然后,执行这个程序。
4.5 创建shared libraries
gcc -fPIC -g -c -Wall a.c
gcc -fPIC -g -c -Wall b.c
gcc -shared -Wl,-soname,libmystuff.so.1 \
-o libmystuff.so.1.0.1 a.o b.o -lc
-fPIC与-fpic比较,fPIC编译的文件比较大,和平台无关,fpic编译的比较小,和平台有关。不用使用-fomit-frame-pointer这个编译参数除非你不得不这样。虽然使用了这个参数获得的函数库仍然可以使用,但是这使得调试程序几乎 没有用,无法跟踪调试。需要使用“-Wl,-export-dynamic”这个选项参数。通常,动态函数库的符号表里面包含了这些动态的对象的符号。 这个选项在创建ELF格式的文件时候,会将所有的符号加入到动态符号表中。可以参考ld的帮助获得更详细的说明。如果在linux可以用``-rdynamic'' 代替``-Wl,export-dynamic''。
在开发过程中,想修改一个库,但该库也用于许多其他程序, 你不希望其他程序使用修改的库,只让一个特定的应用程序测试,一个链接选项:`rpath',它指定特定的程序被编译的运行时库搜索路径。
|
-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH) |
5 Dynamically Loaded (DL) Libraries
使用动态加载库:
|
#include <stdlib.h> #include <stdio.h> #include <dlfcn.h> int main(int argc, char **argv) { void *handle; double (*cosine)(double); char *error; handle = dlopen ("/lib/libm.so.6", RTLD_LAZY); if (!handle) { fputs (dlerror(), stderr); exit(1); } cosine = dlsym(handle, "cos"); if ((error = dlerror()) != NULL) { fputs(error, stderr); exit(1); } printf ("%f\n", (*cosine)(2.0)); dlclose(handle); } |
编译命令为:
|
gcc -o foo foo.c -ldl |
6 参考
浅析C/C++ library的更多相关文章
- 从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler
熟悉WebForm开发的朋友一定都知道,Page类必须实现一个接口,就是IHttpHandler.HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...
- MS SQL统计信息浅析下篇
MS SQL统计信息浅析上篇对SQL SERVER 数据库统计信息做了一个整体的介绍,随着我对数据库统计信息的不断认识.理解,于是有了MS SQL统计信息浅析下篇. 下面是我对SQL Serve ...
- 浅析py-faster-rcnn中不同版本caffe的安装及其对应不同版本cudnn的解决方案
浅析py-faster-rcnn中不同版本caffe的安装及其对应不同版本cudnn的解决方案 本文是截止目前为止最强攻略,按照本文方法基本可以无压力应对caffe和Ross B. Girshick的 ...
- Android Dagger依赖注入框架浅析
今天接触了Dagger这套android的依赖注入框架(DI框架).感觉跟Spring 的IOC差点儿相同吧.这个框架它的优点是它没有採用反射技术(Spring是用反射的),而是用预编译技术.因为基于 ...
- C# 程序性能提升篇-1、装箱和拆箱,枚举的ToString浅析
前景提要: 编写程序时,也许你不经意间,就不知不觉的使程序代码,发生了装箱和拆箱,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环.网络程序(不断请求处理的)等这些时候,减少装箱和拆 ...
- IOCP 浅析
http://www.ibm.com/developerworks/cn/java/j-lo-iocp/ https://msdn.microsoft.com/en-us/library/window ...
- A transition animation compatible Library.
Android5.0之后为我们提供了许多炫酷的界面过渡效果,其中共享元素过渡也是很有亮点的一个效果,但这个效果只能在Android5.0之后使用,那今天我们就来将共享元素过渡效果兼容到Android4 ...
- C# 程序性能提升篇-2、类型(字段类型、class和struct)的错误定义所影响性能浅析
前景提要: 编写程序时,也许你不经意间,就不知不觉的定义了错误的类型,从而发生了额外的性能消耗,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环.网络程序(不断请求处理的)等这些时候 ...
- Reactive Extensions(Rx)并发浅析
Reactive Extensions(Rx)并发浅析 iSun Design & Code .Net并行编程 - Reactive Extensions(Rx)并发浅析 关于Reactive ...
随机推荐
- iis7应用程序池自动关闭问题解决
解决: 应用程序池启动32位应用程序 设置托管管道为集成 (仍然有问题) 图片:123.png 访问网站之前 应用程序池是开启的 访问后 网页报503 service unavailable应用程序池 ...
- 【坑】执行Consumer的时候发生java.net.UnknownHostException错误
[时间]: 2016/4/8 17:30 [问题]: kafka执行Consumer实例的时候,发生了一下错误. kafka配置文件server.properties如下: zookeeper配置文件 ...
- shell 编程基础
1 创建shell脚本文件 要创建一个shell脚本文件,必须在第一行指定要使用的shell,其格式为: #! /bin/bash 接着加上该shell文件的注释,说明该脚本文件用来干什么,有谁创建, ...
- 从JetBrains公司产品给我的商业模式启示
JetBrains是捷克一家公司,专门从事IDE工具的开发,运营的产品有十几个.我因为使用JavaScript IDE工具而了解了WebStorm.进而了解了开发WebStorm的公司JetBrian ...
- 设置xx-net,访问youtube等国外网站
配合使用chrome+xx-net,就可以免费访问youtube等外网了.步骤如下: 1. 按照https://github.com/XX-net/XX-Net/wiki/%E4%BD%BF%E7%9 ...
- algorithm之改变序列算法--待解决
简述:改变序列算法,参见http://www.cplusplus.com/reference/algorithm/?kw=algorithm 待解决问题:iterator_traits.std::mo ...
- 【收藏】Linux添加/删除用户和用户组
1.建用户: adduser phpq //新建phpq用户 passwd phpq ...
- js如何获取select下拉框的value以及文本内容
select下拉框在项目开发中是经常用到的,特别是在联级菜单方面的应用更为广泛.但是,对于一些初学者来说,如何获取下拉框子节点option的value值和文本内容,还是有一点难度的.其他的就不说了,现 ...
- bower解决js的依赖管理
bower解决js的依赖管理 前言: 一个新的web项目开始,我们总是很自然地去下载需要用到的js类库文件,比如jQuery,去官网下载名为jquery-1.10.2.min.js文件,放到我们的项目 ...
- shell ulimit -n
通过ulimit -n命令可以查看linux系统里打开文件描述符的最大值,一般缺省值是1024,