静态链接库与动态链接库

C++静态链接库与动态链接库的优缺点 C++中的静态链接库(Static Link Libraries,通常是.lib或.a文件)和动态链接库(Dynamic Link Libraries,通常是.dll文件在Windows上,或.so文件在Unix/Linux系统上)都是用来在程序中重用代码的手段,但它们在链接和运行时行为上有显著不同。在选择使用静态库还是动态库时,需要根据具体的应用场景、部署需求和性能要求来决定。通常情况下,如果希望简化部署并且程序体积不是主要关注点,静态链接可能是一个好选择; 阅读详情

一、静态链接库
静态链接库的代码在编译时链接到应用程序中,因此编译时库必须存在,并且需要通过 “-L” 参数传递给编译器,应用程序执行时不需要静态库的存在。
静态库的生成
静态库的生成分三步,设计库原码、编译.o文件和使用ar命令生成库。
1. 设计库原码。

//****pt1.c***/
#include <stdio.h>
int pt1(void)
{
printf("I am print1./n");
return 0;
}
//****pt2.c***/
#include <stdio.h>
int pt2(void)
{
printf("I am print2./n");
return 0;
}

2. 编译.o
使用 –c 选项产生目标文件,使用 –O选项优化代码;

# gcc –c –O pt1.c pt2.c

3. 使用ar库
创建静态库libpt.a, 并通过 ar 的 “-r” 选项增加中间目标文件到静态库文件中.

#ar –rsv libpt.a pt1.o pt2.o

4. 静态库的命名规则
为了在编译中正确的查找到库文件,表态库必需以 lib[name].a 的规则命名,如libpt.a.
静态库的使用
1. 调用库代码

/****main.c*******/
int main(void)
{
pt1();
pt2();
return 0;
}

2. 编译链接选项

#gcc –O –o main main.c –L ./-lp

或:

#gcc –O –o main main.c ./libpt.a

其中 –lpt的含义是 libpt.a, “-L ./” 含义是可以在当前目标下查找库文件。
3. 执行目标文件

#./main

Ar命令详解
Ar [drqtpmx] [options] archivefile objfile1 objfile2 …..
参数说明:
-r 将objfile文件插入静态库尾或替换静态库中的同名文件
-x 从静态库文件中抽取库文件objfile
-t 打印静态库中的文件列表
-d 从静态库中删除文件objfile
-s 重置静态库文件索引
-v 创建文件的冗余信息
-c 创建静态文件库


二、动态库
动态库也称为共享库,其代码不会链接到目标文件中,只有当动态库能正确访问时,应用程序才能正确的执行动态链接库函数。应用程序执行动态链接库有两种方式:隐式调用和显式调用。
1. 隐式调用
也称为共享库的静态加裁,其中动态库函数会在应用程序执行开始时加入内存,在应用程序执行完毕后自动卸载。隐式调用的编译方式与静态库一致。隐式调用的动态库必须放在特定的目录内才能被执行。
2. 显式调用
显式调用也称为动态库的动态加裁,编译时可以不显示的提供原动态库文件入名称,但必须遵循dlopen等函数的规则实现调用。应用程序可以在其运行的任意时刻加载或卸载动态链接库。
动态库的生成
动态库的生成主要包括三步:设计库原码、编译位置无关码(PIC)型.o文件、链接动态库。链接动态库的命令包括特殊标志,与链接静态库和链接可执行动态文件有区别,不同的UNIX系统也不尽相同。编译PIC型.o文件的方法一般采用C语言编译器的 “-KPIC” 或者 “-fpic”选项,创建最终动态库的方法一般是采用C语言编译器的 “-G”可者 “-shared”选项,或者直接使用工具ld创建。


1. 设计库原码。

/*pr1.c*/
#include <stdio.h>
int p=1;
void print(void)
{
printf("this is the first dll src./n");
}

 

/*pr2.c*/
#include <stdio.h>
int p=2;
void print(void)
{
printf("this is the second dll src./n");
}

2. 编译位置无关码(PIC)型.o文件和链接动态库(linux和其它使用gcc编译器的UNIX下)

#gcc –fpic –c pr1.c pr2.c
#gcc –shared –o pr1.so pr1.o
#gcc –shared –o pr2.so pr2.o

或者:

#gcc –O –fpic –shared –o pr1.so pr1.c
#gcc –O –fpic –shared –o pr2.so pr2.c

某些版本gcc 也可以使用 “-G”替换”-shared”;


动态链接库的隐式调用
动态链接库的隐式调用分三个步骤:调用库函数代码、编译链接、动态库查找
1. 调用库函数

/*td1.c*/
int main(void)
{
print();
return 0;
}

2. 编译链接选项
可直接将自建动态库文件名作为参数传递给编译器。

#cp pr1.so dll.so
#gcc –O –o td1 td1.c ./dll.so
#./td1

如果无法执行dll.so中的print,可将pr2.so COPY 成dll.so,再执行;
2. 动态链接库的查找
试着将dll.so删除,再可执行 ./td1,则提示夫法找到相应库,

#rm dll.so
#./td1
Dynamic linker: …….
Killed

当需要载入动态库时,UNIX会按一定的方法查找相关的库,上述中UNIX无法定位库文件,所以出错。一般情况下,当前目录是默认查找目标,但有些UNIX系统默认目录不是当前目录,这样库文件在当前目录下也会提示出错。解决方法为:
1)。带路径编译

#mkdir dll
#cp pr1.so ./dll/dll.so
#gcc –O –o td1 td1.c . ./dll/dll.so

当程序执行时会自动到./dll下查找相关库文件。
2)。更改环境变量
UNIX遍历某个特定环境变量的存储路径,来查找动态库,用户可以修改环境变量以达到自动搜索动态库的目的。

#LD_LIBRARY_PATH = ./:dll
#export LD_LIBRARY_PATH
#./td1

注:不同的UNIX所依赖的动态库查找路径环境变量名称不相同;
3. 动态库的更换

#cp pr2.so ./dll/dll.so
#./td1
this is the second dll src.

 

动态链接库的显式调用
显式中,应用程序应该遵循dlopen函数的规则调用动态链接库代码,依次为打开动态库、获取动态对象地址、调用动态库对象、错误检查、关闭动态库。
相关函数族:
1.UNIX中使用dlopen打开动态库:

#include<dlfcn.h>
void *dlopen(const char *pathname, int mode);

dlopen加载动态库,成功时返回指向动态库的句柄,失败时返回NULL,参数说明如下:
pathname 带路径的动态库名
mode 加载方式,可取值:
RTLD_LAZY: 动态库的对象符号在被调用时解释
RTLD_NOW:动态库的对象所有符号在函数dlopen返回前被解释;
2. UNIX中使用dlsym取得动态库中对象地址

#include<dlfcn.h>
void *dlsym(void *handle, const char * name);

dlsym在打开的动态库中搜索给为 name的函数对象或全变量,成功则返回相关地址,失败返回NULL,由于返回的是 void *类型指针,需要类型转换。参数说明如下:
handle 打开的动态库句柄
name 查找的全局变量名或函数名
3. 错误检查 UNIX中使用dlerror显式动态库操作中的错误信息

#include<dlfcn.h>
char *dlerror(void)

本函数为返回最近的错误信息,函数执行后自动将错误信息置为NULL
4. 关闭动态库 动态库使用完后,要关闭,以释放内存

#include<dlfcn.h>
int dlclose(void * handle);

参数说明:
handle 为打开的动态库
应用示例:
以下程序动态的调用以上述创建的动态链接库

/****/
#include<dlfcn.h>
char errs_msg[100];
void main(void)
{
void *pHandle;
void (*pFunc)();
int *p;
pHandle = dlopen("./dll.so",RTLD_NOW);
if (NUll == pHandle)
{
strcpy(errs_msg,"can not find dll.so");
goto ERR;
}
pFunc = (void(*)()) dlsym(pHandle,"print");
if (NUll != pFunc)
{
pFunc();
}else
{
strcpy(errs_msg,"can not find print");
goto ERR;
}
p = (int *)dlsym(pHandle,"p");
if (p)
{
printf("p=%d/n",p);
}else
{
strcpy(errs_msg,"can not find p./n");
goto ERR;
}
dlclose(pHandle);
return 0;
///err handle
ERR:
perror(errs_msg);
dlclose(pHandle);
exit(1);
pwscf与wannier90 Hands-On实战训练(一)——费米面计算为例 系列文章目录 Quantum Espresso Hands-On实战训练(三)——DOS计算 文章目录系列文章目录计算过程pwscf直接得到等能面pwscf和wannier90得到等能面pwscf直接得到等能面1. scf2. nscf3. 后处理pwscf和wannier90得到等能面1. Kpoints2. scf3. nscf4. pw2wan及wannier90.x5. XCrySDen可视化 计算过程 pwscf直接得到等能面 pwscf和wannier90得到等能面 pwscf直接得到等能面 阅读详情

相关推荐

2023东华大学OJ机试题22-70

东华大学计算机考研复试机试22 约瑟夫环223、整除的尾数24、回文质数25、汽水瓶26、阶乘最后的非0位27、算菜价28、 水果价格29、求奇数的乘积30、求最晚和最早日期31、素数32、计算e33 数字之和34 繁殖问题35 奇妙的数字36 整除的尾数37 黑色星期五38 树39 约瑟夫环40 最大与最小41 环42 求数列项43 最高频率44 三艘船45 回文数46 特殊四位数47 最大值48 数列149 修理牛棚50 按要求输出序列51 部落人乘法52 序列53 双重回文数54 等差数列55 人见人

m0_49263811的博客 2598

CMake静态库动态库的构建和链接之工程实用篇

在这里不再赘述。Windows平台下可用cmake-gui生成vs的.sln工程,Linux平台下可以运行cmake命令。

taifyang的博客 1万+

深入理解「二进制掩码」:从原理到实践

二进制掩码本质上是一个二进制数,用于通过位操作(如与、或、非、异或等)选择性地操作目标数据的某些位。掩码的每一位(bit)可以看作一个“开关”,决定是否对目标数据的对应位进行操作。二进制掩码是位操作的灵魂,掌握它不仅能提升代码效率,还能解锁许多高级编程技巧。从基础的位提取到复杂的子集枚举,掩码的应用无处不在。希望本文的讲解和代码示例能帮助你快速上手,并在实际项目中灵活运用。如果你有更多关于掩码的疑问或应用场景,欢迎在评论区留言交流!

m0_73494933的博客 2432

gcc/g++静态与动态链接库

文章目录库文件静态链接库动态链接库库的生成与使用静态库动态库参考文章 库文件 首先说明要对库有一个比较直观的理解。库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都依赖很多基础的底层库,不可能每个人的代码都从零开始,公共代码需要反复使用,就把这些代码编译成为“库”文件,因此库的存在意义非同寻常。 本质上说来库是一种可执行代码的二进制形式(注,其本身不可执行),可以被操作系统载入内存执行。 我们在链接的时候有两种库:动态链接库和静态链接库 静态链接库 在链接阶段,会将汇编生成的目标文件.o与引用到的

Charles Ren's Tech Blog 8764

基于Apache SeaTunnel构建CDC数据同步管道

Apache SeaTunnel是一个数据集成开发平台,其发展经历了几个重要阶段:ETL时代(90年代):面向结构化数据库的数据同步,用于构建数据仓库。MPP和分布式技术流行:使用技术如Hive进行数据仓库的构建。此阶段主要使用mapreduce程序进行数据搬运和转换。数据湖技术流行:重视数据集成,强调先同步数据至数据湖仓储,再进行业务面向的转换和设计。CDC,即变更数据捕获,是一种捕获数据库变更事件(如插入、更新、删除)的技术。

weixin_54625990的博客 2172

科研笔记:怎样写好博士论文?

博士论文外审避坑指南与写作要点 博士论文外审的核心关注点呈现5级优先级:科研成果(硬指标)>创新性>逻辑结构与场景合理性>文献综述与规范性>工作量验证。外审专家会重点核查:1)成果清单是否达标;2)创新点是否真实明确;3)章节逻辑是否自洽、应用场景是否细化;4)文献综述是否构建"研究坐标系";5)实验/理论支撑是否充分。需特别注意三大雷区:科学错误(直接挂稿)、伪创新、场景不合理。写作时应强化选题依据的场景细化,通过"发展阶段+跨领域对比"提升文献综述质量。

Grow into a more wonderful you 1064

详解动态库&&静态库、动态链接&&静态链接

库函数、动态库、静态库、动态链接、静态链接

m0_64388758的博客 2440

【VoxCPM2】在Windows上从零搭建VoxCPM2 语音生成和语音克隆AI算法

建议你了解清楚VoxCPM2,再来考虑是否需要自己在本地搭建。

AnChenliang_1002的博客 753

【Linux系统】动静态库

动静态库制作,安装与使用,最后介绍动态库的原理

weixin_74113106的博客 1217

【AI智能体】Spring AI Tool 从使用到实战详解

Spring AI Tool

congge 5865

外骨骼机器人(五):步态分析之正常步态

研究病理步态之前,需要了解正常步态,作为判断标准。但是需要记住两个问题:1.“正常”因人而异,性别、年龄、身体情况都需要考虑在内,因此,需要对不同的个体选择合适的正常标准;2.即使病人的步态与正常步态有某种不同,这也不能说明这是不可取的,也不能说明应该把它变成“正常”步态。许多步态异常是对病人的一些问题的一种补偿,尽管异常,但它们仍然是有用的。步态周期的定义是连续为两次发生重复行走事件之间的时间间隔。尽管可以选择任何事件来定义步态周期,但通常使用一只脚接触地面的瞬间(“初始接触”)是方便的。

行者无疆的博客 1995

静态链接库与动态链接库详解

以下内容源于C语言中文网相关内容的学习整理,如有侵权请告知删除。

主要记录嵌入式学习与开发过程。 9307

华为OD机试 - 压缩日志查询(Python/JS/C/C++ 双机位C卷 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。某设备需要记录每分钟检测到的指标值。为了节约存储空间,将连续相同指标值的记录合并。压缩之前:202411231000,11 202411231001,11 202411231002,12 202411231003,12 202411231004,

学Java,找哪吒 1880

6、静态链接库、动态链接库

静态链接库、动态链接库

融码一生:专注 Python、C/C++、Linux、机器学习 & 深度学习、NLP、算法领域分享 1610

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【基础】动态链接库/静态链接库的区别

C或C++程序从源文件到生成可执行文件需经历4个阶段分别为预处理、编译、汇编和链接。链接阶段所要完成的工作,是将同一项目中各源文件生成的目标文件和程序中用到的库文件整合为一个可执行文件。虽然库文件明确用于,但编译器提供了2种实现链接的方式,分别称为静态链接和动态链接。采用静态链接方式实现链接操作,的库文件称为静态链接库;采用动态链接方式实现链接操作,的库文件称为动态链接库。在Linux发行版系统中,静态链接库文件的后缀名通,动态链接库的后缀名通;,动态链接库的后缀名。...

weixin_41838721的博客 8122

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

静态链接库和动态链接库的区别

目录 1、链接库概述 2、静态链接库 2.1、编辑测试文件 2.2、将.c 编译生成 .o文件 2.3、由 .o 文件创建.a静态库 2.4、在程序中使用静态库 2.5、生成目标程序main,然后运行 3、动态库(隐式链接) 3.1、由 .o创建.so动态库 3.2、隐式方式使用动态库 3.3、动态库的初始化和解析 1、动态库的构造和析构函数机制 2、全局变量初始化 4.........

weixin_36670529的博客 4372

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

动态链接库和静态链接库的区别

静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序运行的时候不再需要其它的库文件;动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此需要相应DLL文件的支持。  静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的

4万+

静态链接库和动态链接库

一、静态链接库和动态链接库 1、制作方法 2、动态库制作中extern “C” _declspec(dllexport)导出,才会生成lib文件 3、查看动态库生成的接口 二、静态链接和动态链接 1、静态库的链接 2、动态库的链接 1)LoadLibrary、GetProcAddress、FreeLibrary 2)导出lib的动态库可根据lib和头文件隐式链接 三、 #ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else

qq_43148810的博客 4935

静态链接库与动态链接库区别

一、        静态链接库与动态链接库区别 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包

OnWay的专栏 3720

【C++】中动态链接库和静态链接库的区别

动态链接适用于那些希望减少最终二进制文件大小、允许独立更新库代码或需要在多个程序间共享库代码的情况。静态链接则更适合于那些需要确保二进制文件独立运行、不依赖于外部文件或需要更严格控制版本的应用场景。选择哪种方式主要取决于项目的具体需求、目标平台以及开发团队的偏好。

wangnaisheng的专栏 1753
上一篇: Extern “C” 用法小结
下一篇: linux/unix文件描述符
comlc
博客等级 码龄19年 9粉丝 34原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值