C++静态链接与动态链接详解

目录
  • 一、GCC工作流程
  • 二、静态链接与动态链接
    • 1、静态链接
    • 2、动态链接
  • 总结

一、GCC工作流程

预处理:把#头文件展开,进行宏替换,去掉注释(生成.i文件)

编译:把预处理后的文件生成汇编文件(.s文件),主要是检查语法、语义问题

汇编:把汇编文件生成目标文件(.o文件)

链接:将函数库中相应的代码组合到目标文件,生成可执行文件(默认a.out文件)

o文件不会立即执行,因为可能出现:一个.cpp文件中的函数引用了另一个.cpp文件中定义的符号/调用了某个库文件中的函数。链接的目的就是将这些文件对应的目标文件链接成一个整体,从而生成可执行文件。

二、静态链接与动态链接

程序库:包含数据和执行代码的文件,不能单独执行,可以作为程序库的一部分来完成某些功能。

库的存在可以使程序模块化,可以加快程序的再编译,实现代码复用,便于更新程序

程序库又分为静态链接库与动态链接库

1、静态链接

在链接阶段,将汇编生成的.o文件和所需要的库一起链接打包到可执行文件中去,程序运行的时候不再调用其它的库文件

一个静态库,可以看作是一些目标代码的集合,在可执行程序运行前就已经加入到执行代码中,成为执行程序的一部分。

静态链接的优点:对运行环境依赖小,具有较好的兼容性。

静态链接的缺点:生成的程序较大,需要更多的系统资源(所需的所有库都被打包进可执行文件了),在装入内存中消耗更多时间

一旦库函数有了更新,必须重新编译应用程序

此处,我们制作实现加减乘除的静态库,首先编写add.c、sub.c、mul.c、div.c文件及对应.h文件,另外编写text.c文件进行测试。gcc -c 生成目标文件.o,然后将.o文件打包,制作静态库libtext.a

2、动态链接

静态库存在的问题:

(1)若两个.o文件都使用同一个静态库,那么内存中会拷贝2份静态库的代码,然 后分别与两个.o文件一起打包到可执行文件中,造成空间浪费。

举个例子:某个静态库占1M内存,有2000个.o文件使用这个静态库,内存中有2000个静态库的代码(将近2000GB),空间浪费严重。

(2) 所需的库被拷贝到可执行文件中去了,如果某个库更新了,则与它相关的所有可执行文件都需要重新编译。

为了解决这两个问题,引出动态库(又称共享库),动态库在程序编译时,并不会被链接到目标代码中,而是在运行时载入,不同应用程序如果调用相同的的库,内存里只有一份共享库的实例,避免了浪费。由于动态库在运行时才被载入,也解决了静态库对程序的更新、部署和发布带来的马粪,用户只需要更新动态库即可。

动态链接的优点:链接时,仅仅建立与所需库函数之间的关系;

在程序运行时才将所需资源调入可执行程序;

简化程序的升级,有较小的程序体积;

实现进程之间的资源共享,内存中只有一份动态库的实例,避免充分拷贝

动态链接的缺点:依赖动态库,不能独立运行

动态库依赖版本问题严重

同样的,我们制作制作实现加减乘除的动态库。

我们把动态库.so和测试文件.c拷贝当前目录,使得系统加载可执行文件时,能够知道所依赖的库的名字,但是还需要找到动态库的绝对路径,此时需要系统动态载入器(dynamic linker/loader)。对于elf格式的可执行程序,是由ld-linux.so*来完成的。搜索elf文件的DT_PATH段(环境变量)LD_LIBRARY_PATH,/etc/ld.so.cache文件列表,/urs/lib目录找到库文件后将其载入内存。

动态库加载失败的解决办法:这里给出两个解决办法,来找到动态库

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Python调用C/C++动态链接库的方法详解

    本文以实例讲解了Python调用C/C++ DLL动态链接库的方法,具体示例如下: 示例一: 首先,在创建一个DLL工程(本例创建环境为VS 2005),头文件: //hello.h #ifdef EXPORT_HELLO_DLL #define HELLO_API __declspec(dllexport) #else #define HELLO_API __declspec(dllimport) #endif extern "C" { HELLO_API int IntAdd(in

  • 在C语言中调用C++做的动态链接库

    今天在做东西的时候遇到一个问题,就是如何在C语言中调用C++做的动态链接库so文件 如果你有一个c++做的动态链接库.so文件,而你只有一些相关类的声明, 那么你如何用c调用呢,别着急,本文通过一个小小的例子,让你能够很爽的搞定. 链接库头文件: head.h class A { public: A(); virtual ~A(); int gt(); int pt(); private: int s; }; firstso.cpp #include <iostream> #include &

  • 详解C++的JSON静态链接库JsonCpp的使用方法

    JsonCpp部署方法: 在http://sourceforge.net/projects/jsoncpp/中下载最新版本的jsoncpp库源码. 之后将jsoncpp-src-版本号-tar.gz解压出来,打开makefiles中的jsoncpp.sln进行编译,之后build文件夹下的vs71\debug\lib_json中会有一个.lib静态链接库. JsonCpp主要包含三种类型的class:Value Reader Writer. jsoncpp中所有对象.类名都在namespace

  • C++编写DLL动态链接库的步骤与实现方法

    本文实例讲述了C++编写DLL动态链接库的步骤与实现方法.分享给大家供大家参考,具体如下: 在写C++程序时,时常需要将一个class写成DLL,供客户端程序调用.这样的DLL可以导出整个class,也可以导出这个class的某个方法. 一.导出整个class 方法很简单,只需要在类的头文件中class和类名之间加上_declspec(dllexport),同时在另外一份提供给客户端调用程序使用的类的头文件中class和类名之间加上_declspec(dllimport).为了能让客户端程序和D

  • Python 调用VC++的动态链接库(DLL)

    1. 首先VC++的DLL的导出函数定义成标准C的导出函数: 复制代码 代码如下: #ifdef LRDLLTEST_EXPORTS #define LRDLLTEST_API __declspec(dllexport) #else #define LRDLLTEST_API __declspec(dllimport) #endif extern "C" LRDLLTEST_API int Sum(int a , int b); extern "C" LRDLLTE

  • C++ Cmake的构建静态库和动态库详解

    目录 静态库和动态库的区别 构建示例 ADD_LIBRARY 同时构建静态和动态库 SET_TARGET_PROPERTIES 动态库的版本号 安装共享库和头文件 使用外部共享库和头文件 解决 :make后头文件找不到的问题 解决:找到引用的函数问题 特殊的环境变量CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH 总结 静态库和动态库的区别 1.静态库的扩展名一般为".a"或者".lib":动态库的扩展名一般为".so"

  • Oracle静态注册与动态注册详解

    一.概述: Oracle的注册就是将数据库作为一个服务注册到监听程序.客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到这个数据库.这个服务名可能与实例名一样,也有可能不一样. 在数据库服务器启动过程中,数据库服务器会向监听程序注册相应的服务(无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务.) 相当于是这样:在数据库服务器和客户端之间有一监听程序(Listener),在监听程序中,会记录相应数据库对应的服务名(一个数据库可

  • C++静态链接与动态链接详解

    目录 一.GCC工作流程 二.静态链接与动态链接 1.静态链接 2.动态链接 总结 一.GCC工作流程 预处理:把#头文件展开,进行宏替换,去掉注释(生成.i文件) 编译:把预处理后的文件生成汇编文件(.s文件),主要是检查语法.语义问题 汇编:把汇编文件生成目标文件(.o文件) 链接:将函数库中相应的代码组合到目标文件,生成可执行文件(默认a.out文件) o文件不会立即执行,因为可能出现:一个.cpp文件中的函数引用了另一个.cpp文件中定义的符号/调用了某个库文件中的函数.链接的目的就是将

  • Linux链接命令的实例详解

    Linux链接命令的实例详解 一 语法 ln -s [源文件] [目标文件] 命令英文含义:link 功能描述:生成链接文件 选项:-s 创建软链接 二 硬链接特征 原文件和硬链接文件删除其中任何一个都没问题. 三 硬链接实战 [root@localhost ~]# cd test [root@localhost test]# ls bcd [root@localhost test]# ln bcd abc.hard [root@localhost test]# ll total 0 -rw-r

  • 浅谈CMake配置OpenCV 时静态链接与动态链接的选择

    方法: 添加OpenCV_STATIC 选项,设置为不勾选,在cmake配置的时候就会选择动态库 否则,cmake 配置的时候会设置为静态库 以上这篇浅谈CMake配置OpenCV 时静态链接与动态链接的选择就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • Vue页面切换和a链接的本质区别详解

    Vue-router是伴随着Vue框架出现的路由系统,它也是公认的一种优秀的路由解决方案.在使用Vue-router时候,我们常常会使用其自带的路径跳转组件Link,通过<Link to="path"></Link>实现跳转,这和传统的<a href="path" rel="external nofollow" ></a>何其相似!但它们到底有什么具体的区别呢? 对比<a>,Link组件

  • Go创建Grpc链接池实现过程详解

    目录 常规用法 创建链接池 创建链接池接口 实现链接池接口 关闭链接 扩缩容 性能测试 常规用法 gRPC 四种基本使用 请求响应模式 客户端数据流模式 服务端数据流模式 双向流模式 常见的gRPC调用写法 func main(){ //... some code // 链接grpc服务 conn , err := grpc.Dial(":8000",grpc.WithInsecure) if err != nil { //...log } defer conn.Close() //.

  • IOS 静态方法与动态方法详解

    IOS 静态方法与动态方法详解 1.问题提出 iOS中有静态方法与动态方法,那么两种方法的异同是什么? 2.问题分析 因为每个对象都由相应的数据结构与方法相构成,一个程序可能有多个属于同一个类的对象,而每个对象的数据结构应该是不一的,但方法是相同的,若为每个对象开辟内存空间来存储方法,必然是对内存空间极大的浪费.因此apple是通过类对象与元类来解决这个问题的. 从根本来说,c++.objective-c.java都发源于c语言,因此这些语言实际上可以理解了经过封装的c语言,所以它们更加方便使用

  • C语言实现静态顺序表的实例详解

    C语言实现静态顺序表的实例详解 线性表 定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识.只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作. 接下来看看静态的顺序表,直接上代码: SeqList.h #define _CRT_SECURE_NO_WARNINGS 1 #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #include <stdio.h> #include <stdlib.h&g

  • JVM 方法调用之动态分派(详解)

    1. 动态分派 一个体现是重写(override).下面的代码,运行结果很明显. public class App { public static void main(String[] args) { Super object = new Sub(); object.f(); } } class Super { public void f() { System.out.println("super : f()"); } public void f(int i) { System.out

随机推荐