一.链接库
1.静态链接库
1.1 windows(.lib)
在计算机科学里,静态库(英语:Static library, Statically-linked library),或称静态库,是一个外部函数与变量的共同体。静态库的文件内容,通常包含一堆程序员自定的变量与函数,其内容不像动态链接库那么复杂,在编译期间由编译器与连接器将它集成至应用程序内,并制作成目标文件以及可以独立运作的可执行文件。
例子一:为什么不用.cpp文件直接对工程进行链接,因为这样会泄露代码,而如果使用链接库的时候,就可以不会把代码泄露给别人。
例子二:静态链接库不同于动态链接库,静态链接库直接把库放到了exe可执行文件中。
1.2 linux(.a)
在linux中编译c++的时候,使用了gcc进行编译,可以生成.o的目标文件,使用:
gcc -c test.c
//生成了.o的文件
使用ar命令将生成的.o文件生成为.a的静态链接库文件:
ar的命令:
c -- 如果库文件不存在,生成新的库文件,并不打印警告
r -- 代替库中已有的文件或者插入新的文件
v -- 输出详细信息
d -- 删除库中的某个目标文件
t -- 列出归档文件中包含的目标文件
//这里我们使用的是rcv参数
ar rcv libtest.a test.o
//生成了.a的静态连接库
将我们生成的静态链接库可以链接到某个c程序的使用。
gcc main.c -L. -ltest
//当我们链接时,指定 -lxxx,链接器就会在指定的目录查找 libxxx.a 或 libxxx.so 文件
这里我们进行一个完整的静态链接库的编写:
代码:
# sub.cpp
int sub(int a, int b)
{
return a - b;
}
#sub.h
#pragma once
int sub(int a, int b);
#main.cpp
#include<stdio.h>
#include"sub.h"
int main()
{
printf("%d", sub(9, 4));
return 0;
}
2.动态链接库
2.1windows
DLL:Dynamic Link Library,即动态链接库,这种库包含了可由多个程序同时使用的代码和数据。
它是microsoft在windows操作系统中实现共享函数库概念的一种实现方式。
DLL最初用于节约应用程序所需要的磁盘和内存空间。早前,在传统的非共享库中,一部分代码简单地附加到调用的程序中。如果两个程序同时调用同一个子程序,就会出现两份那段代码。相反,许多应用共享的代码能够切分到一个DLL中,在硬盘上存为一个文档,在内存中只需使用一个实例。
当某个程序或 DLL 在另一个 DLL 中使用 DLL 函数时,将创建一个依赖项。 因此,该程序不再是独立的,如果依赖项断开,该程序可能会遇到问题。 例如,如果发生下列操作之一,则该程序可能无法运行:
-
依赖 DLL 升级到新版本。
-
固定的 DLL 是固定的。
-
早期版本会覆盖依赖 DLL。
-
将从计算机中删除依赖 DLL。
以下列表介绍了 Windows 2000 和更高版本的 Windows 操作系统中引入的更改,以帮助最大限度地减少依赖性问题:
-
Windows 文件保护
在 Windows 文件保护中,操作系统可防止未经授权的代理更新或删除系统 Dll。 因此,当程序安装尝试删除或更新定义为系统 DLL 的 DLL 时,Windows 文件保护将查找有效的数字签名。
-
专用 Dll
专用 Dll 允许您将程序与对共享 Dll 所做的更改隔离。 专用 Dll 使用版本特定的信息或一个空的本地文件来强制实施该程序使用的 DLL 版本。 若要使用专用 Dll,请在程序根文件夹中找到您的 Dll。 然后,对于新程序,向 DLL 中添加版本特定的信息。 对于旧程序,请使用空的本地文件。 每个方法都通知操作系统使用位于程序根文件夹中的专用 Dll。
查找顺序:
-
假如安全DLL搜索模式启用,搜索顺序如下:
-
应用程序所在的路径
-
Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。
-
16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。
-
Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。
-
当前目录
-
PATH环境变量指定的路径。请注意,这并不包括每个应用程序的应用程序路径注册表项中指定。在应用程序路径注册表项的键值并不作为DLL的搜索路径。
//应用程序所在目录→当前目录→Windows SYSTEM目录→Windows目录→PATH环境变量指定的路径
假如安全DLL搜索模式禁用,搜索顺序如下:
-
应用程序所在的路径
-
当前目录
-
Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。
-
16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。
-
Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。
-
PATH环境变量指定的路径。请注意,这并不包括每个应用程序的应用程序路径注册表项中指定。在应用程序路径注册表项的键值并不作为DLL的搜索路径。
2.2linux
Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件。
编写动态链接库:
-
编写源文件
-
将一个或几个源文件编译链接,生成共享库。
-
通过 -L<path>-lxxx 的gcc选项链接生成的libxxx.so。
-
把 libxxx.so 放入链接库的标准路径,或指定 LD_LIBRARY_PATH,才能运行链接了libxxx.so的程序。
gcc -fPIC -c add.c sub.c
//编译为.o文件
//其中,PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性
gcc -shared -o libmymath.so sub.o add.o
//链接,把两个.o文件生成为一个.so文件(动态链接库)
//-shared是链接选项,告诉gcc生成动态库而不是可执行文件
但是生成后运行出错,原因:
对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索:
-
elf文件的DT_RPATH段
-
环境变量LD_LIBRARY_PATH
-
/etc/ld.so.cache文件列表
-
/lib/
-
/usr/lib
找到库文件后将其载入内存。
所以,我们想让程序找到自己写的动态链接库,有如下方法:
-
指定 LD_LIBRARY_PATH 环境变量为 libmymath.so 文件所在的目录
-
编辑/etc/ld.so.conf文件,加入库文件所在目录的路径; 同时,运行ldconfig ,该命令会重建/etc/ld.so.cache文件
-
把 libmymath.so 拷贝到/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作
来源:freebuf.com 2020-11-12 09:31:35 by: 夏鸥兔兔2000
请登录后发表评论
注册