浅析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 ...
随机推荐
- file_get_contents函数和curl函数不能用
某天file_get_contents()突然不能用了,检查了下php配置文件 allow_url_fopen=on 没问题 各种重启也没用 最后在ssh下执行 chmod 755 /etc/re ...
- .net(C#)操作文件的几种方法汇总
.net(C#)操作文件的几种方法汇总 System.IO命名空间下类的用法:在System.IO名称空间中包含了用于文件输入输出的主要类.File:实用类,提供许多静态方法,用于移动.复制和删除文件 ...
- jQuery插件实例一:年华时代插件Alert对话框
在工作中使用jQuery插件相信对于程序员来说非常普遍,在网络上也有很多优秀的插件可供大家使用,功能非常强大.在之前用过的一些插件中,有些太过追求功能的强大和可配置性,造成使用的复杂度上升.个人认为与 ...
- 关于使用,NI采集卡+labview信号采集,问题交流【第二贴】
*** 采集卡 NI PCI-6534: max sample rate 20MHz:32位的数字输入,数字输出. ***输入信号: 峰峰值,4.16V 最小值 -80mV 频率 ...
- c++中的virtual函数,即虚函数
c++中的虚函数主要是用来实现多态的,虽然都同时指向父类的实例.但调用的确实子类的函数,这个有点像java的接口和实现的关系了.一个接口有多种实现,一个接口对象调用的是哪个实现的方法,这个就是多态了 ...
- mysql几个命令
1.格式化输出 select * from mysql.user\G 2.显示版本 show version() 3.显示引擎 show engines mysql> show engines; ...
- Codeforces Round #353 (Div. 2) C Money Transfers
题目链接: http://www.codeforces.com/contest/675/problem/C 题意: 给一个数组,每个数与他相邻的数相连,第一个与最后一个相连,每个数的数值可以左右移动, ...
- xml给提示
1. FAQ:不给提示: a) window – preferences – myeclipse – xml – xml catalog b) User Specified E ...
- Leetcode#137 Single Number II
原题地址 遍历所有数字,统计每一位出现的次数,模3即为只出现一次的数字在那一位的情况. 代码: int singleNumber(int A[], int n) { ] = {}; ; i < ...
- libxml2 crash
在 xmlParseFile 就那么挂在里面了 只有一个dll 和一堆头文件 没法调试 有如下猜想(感谢fb 和 array) 这是一个unhandled exception可以catch看看 也许是 ...