C++:静态库、动态库、头文件

C++中提供某个库,往往有三种方法:

头文件(.h)+静态库(.a)

头文件(.h)+动态库(.so)

头文件(.h)+源代码(.cpp)

注意,动态函数库同共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库, 文件后缀是.dll)

共享库/动态库   也就是.so的库

共享库的命名

每个共享函数库都有个特殊的名字,称作“soname”。soname名字命名必须以“lib”作为前缀,然后是函数库的名字,然后是“.so”,最后是版本号信息。不过有个特例,就是非常底层的C库函数都不是以lib开头这样命名的。

/usr/lib/libreadline.so.3 是一个完全的完整的soname

每个共享函数库都有一个真正的名字(“real name”),它是包含真正库函数代码的文件。真名有一个主版本号,和一个发行版本号。最后一个发行版本号是可选的,可以没有。主版本号和发行版本号使你可以知道你到底是安装了什么版本的库函数。另外,还有一个名字是编译器编译的时候需要的函数库的名字,这个名字就是简单的soname名字,而不包含任何版本号信息。

另外,编译器在请求库时使用的名称(我将其称为“链接器名称”),这只是没有任何版本号的soname。

管理共享库的关键是这些名称的分离。程序在内部列出他们需要的共享库时,应该只列出他们需要的soname。相反,创建共享库时,只能创建具有特定文件名的库(具有更详细的版本信息)。当您安装新版本的库时,将其安装在几个特殊目录之一中,然后运行程序ldconfig(8)。ldconfig检查现有文件,并将声名创建为真实名称的符号链接,以及设置缓存文件/etc/ld.so.cache(稍后描述)。



LINUX,库的使用

1.1 静态库命名规则

Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为.a。

1.2 若想要创建一个静态库

首先写静态库头文件和源文件


Linux创建静态库过程如下:

-  首先,将代码文件编译成目标文件.o(StaticMath.o)


也就是做到汇编结束这一步,这里,把头文件和源文件放在同一目录,g++源文件即可(源文件中include头文件)

  然后,通过ar工具将目标文件打包成.a静态库文件

生成了静态库libstaticmath.a

如下


注意这个目录下的东西,包含头文件,源文件,和生成的静态库

1.3 使用静态库

编写测试代码


include 静态库的头文件

Linux下使用静态库,只需要在编译的时候,指定静态库的搜索路径(-L选项)、指定静态库名(不需要lib前缀和.a后缀,-l选项)

如:# g++ TestStaticLibrary.cpp -L../StaticLibrary -lstaticmath

-  -L:表示要连接的库所在目录

-  -l:指定链接时需要的动态库,编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.a或.so来确定库的名称。


2.1 动态库命名规则:

动态链接库的名字形式为 libxxx.so,前缀是lib,后缀名为".so"。

-  针对于实际库文件,每个共享库都有个特殊的名字"soname"。在程序启动后,程序通过这个名字来告诉动态加载器该载入哪个共享库。

 在文件系统中,soname仅是一个链接到实际动态库的链接。对于动态库而言,每个库实际上都有另一个名字给编译器来用。它是一个指向实际库镜像文件的链接文件(lib+soname+.so)。


2.2 创建动态库

编写四则运算动态库代码:


首先,生成目标文件,此时要加编译器选项-fpic


fPIC 创建与地址无关的编译程序(pic,position independent code),是为了能够在多个应用程序间共享。  这里生成了.o文件,也就是做到汇编之后

然后,生成动态库,此时要加链接器选项-shared


-shared指定生成动态链接库。


此时文件夹中生成了动态库 libdynmath.so*

2.3 使用

测试代码:

编译的时候(和静态库一样)

g++ TestDynamicLibrary.cpp -L../DynamicLibrary -ldynmath


但此时还没法运行,因为还找不到这个动态库

如何定位和执行动态库呢:

1)        当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)。

2)        对于elf格式(也就是linux下可执行文件的默认格式)的可执行程序,是由ld-linux.so*来完成的,它先后搜索:

1、elf文件的 DT_RPATH段,也即编译时指定的搜索路径

2、环境变量LD_LIBRARY_PATH制定的路径  (不需要root权限)

3、/etc/ld.so.cache文件列表指定的路径  (修改这个需要root权限)

4、默认路径/lib/,/usr/lib 目录       (也需要root权限)

找到库文件后将其载入内存。

如何让系统能够找到它:

-  如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。

-  如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下:

--  编辑/etc/ld.so.conf文件,加入库文件所在目录的路径

--  运行ldconfig ,该命令会重建/etc/ld.so.cache文件

或者

也可以把路劲加入到LD_LIBRARY_PATH里,此时不需要root权限 如下:

export LD_LIBRARY_PATH=/export/apps/anaconda2/2.4.1/lib/:$LD_LIBRARY_PATH (在开头添加)

但这样只是临时修改,重启或者打开新的shell需要重新设置

如果想永久添加:

~/.bashrc或者~/.bash_profile中加入 export 语句,前者在每次登陆和每次打开 shell 都读取一次,后者只在登陆时读取一次。

我的习惯是加到~/.bashrc中,在该文件的未尾,可采用如下语句来使设置生效:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib(在末尾添加


3 库相关命令

3.1   .nm命令

有时候可能需要查看一个库中到底有哪些函数,nm命令可以打印出库中的涉及到的所有符号。库既可以是静态的也可以是动态的。nm列出的符号有很多,常见的有三种:

-  一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;

-  一种是库中定义的函数,用T表示,这是最常见的;

-  一种是所谓的弱态"符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。

$nm libhello.h


3.2   ldd命令

ldd命令可以查看一个可执行程序依赖的共享库,例如我们编写的四则运算动态库依赖下面这些库:


此时,后面有地址的,都是链接器能找到的库

如果找不到的库,会出现这样:


3.3 查找库

可以使用ls /usr/lib |grep lib查看自己是否有需要的库文件,当然还需查看其它库文件目录:echo $LD_LIBRARY_PATH里面一般可以看到七八个已经定义好的库文件搜索路径。


也可使用 pkg-config

其有一些常用参数

也可用 

sudo updatedb 

locate eigen3                                 (库名称)






最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容