浅析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 ...
随机推荐
- visualgo 数据结构与算法可视化工具
推荐可视化数据结构与算法工具 http://zh.visualgo.net/
- html转义函数
public static String filter(String message) { if (message == null) return (null); char content[] = n ...
- NSString+NSStringForJava.m
// // NSString+NSStringForJava.m // NSStringCategory // // Created by Ryan Tang on 12-10-17. // Copy ...
- 程序开发心理学阅读笔记——第II篇
作为社会行为的软件开发程序开发组->程序开发团队->程序开发项目1.要判断程序员的某个集体是否构成一支团队,要看其中的成员以何种方式相互协作,以共同开发软件产品.2.健康的团队要始终能够保 ...
- 团队开发(NABC模型)
1.NEED(需求) 基于铁大目前打电话订水的现状,我们发现了一些问题,例如不能及时送到水,水源不足等问题.本来手机在我们生活中就是非常普及的,尤其是对我们大学生来说,我们似乎患上了“手机依赖症”,没 ...
- centos中设置apache显示目录列表
apache中显示目录列表 在http.conf中加入如下代码(如有虚拟主机配置,加在虚拟主机配置段内),并把主目录内的index.pho,index.html,index.htm文件删除 复制代码 ...
- VS2013 IIS Express 添加MIME映射
VS2013,则可以直接在IIS Express中添加MIME映射.操作如下: 1.在DOS窗口下进入IIS Express安装目录,默认是“C:\Program Files\IIS Express” ...
- android开发 缩放到指定比例的尺寸
一种通过matrix矩阵缩放: //使用Bitmap加Matrix来缩放 public static Drawable resizeImage(Bitmap bitmap, int w, int h) ...
- 设计模式之状态模式(State)
状态模式原理:随着状态的变化,对象的行为也发生变化 代码如下: #include <iostream> #include <string> #include <list& ...
- 【BZOJ】【1010】【HNOI2008】玩具装箱Toy
DP/斜率优化 根据题目描述很容易列出动规方程:$$ f[i]=min\{ f[j]+(s[i]-s[j]+i-j-1-L)^2 \}$$ 其中 $$s[i]=\sum_{k=1}^{i} c[k] ...