美文网首页
C++:静态库、动态库、头文件

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

作者: 循梦渡 | 来源:发表于2020-12-03 19:58 被阅读0次

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                                 (库名称)



相关文章

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

    C++中提供某个库,往往有三种方法: 头文件(.h)+静态库(.a) 头文件(.h)+动态库(.so) 头文件(....

  • 动态库 静态库

    C++静态库与动态库

  • iOS的Framework静态库

    静态库VS动态库 静态库不需要签名,动态库需要签名。 制作混编静态库 库内部Swift调用OC的头文件Swift调...

  • 静态库与动态库区别

    本文动态库、静态库区别部分转载自C++静态库与动态库 程序的编译过程如上图 静态库: 之所以成为【静态库】,是因为...

  • QT中dll的生成及使用

    C++中的库分为三种:静态库、动态库和导入库 1、静态库:     静态库扩展名为.lib,静态链接(即代码会直接...

  • cocoapods的引用

    找不到头文件 cocoapods导入一个第三方的库(开源库或者静态/动态库),然后导入这个库的头文件,编译报错,说...

  • Java 调用本地代码库

    什么是动态链接库 C/C++编译出来的库有两种:静态链接库和动态链接库。 静态库后缀名在Windows上是.lib...

  • iOS 静态库和动态库的制作

    静态库和动态库 一、静态库和动态库的存在形式 静态库: .a 和 .framework 动态库: .dylib 和...

  • Swift 静态库调研

    一、关于库的背景知识1、静态库和动态库静态库动态库系统动态库Cocoa Touch Framework静态库 v....

  • C/C++编程知识:Linux 动态库相关知识整理

    动态库和静态库在C/C++开发中很常见,相比静态库直接被编译到可执行程序,动态库运行时加载使得可执行程序的体积更小...

网友评论

      本文标题:C++:静态库、动态库、头文件

      本文链接:https://www.haomeiwen.com/subject/kdumwktx.html