当前位置: 首页 > news >正文

静态链接(7/13)

在一个软件项目中,为了完成特定功能,除了自定义函数,还可以使用别人已经封装好的函数库,如 C 函数库。库函数的使用避免了重复“造笼子”的重复工作,提高了代码复用率,大大减轻了软件开发的工作量。

库分为静态库和动态库。

  • 静态库。如果在项目中引用了库函数,则在编译时,链接器会将引用的函数代码或变量,链接到可执行文件里,和可执行程序组装在一起,这种库被称为静态库,即在编译阶段链接的库。
  • 动态库。在编译阶段不参与链接,不会和可执行文件组装在一起,而是在程序运行时才被加载到内存参与链接,因此又叫动态链接库。

静态库的本质其实就是可重定位目标文件的归档文件,使用 ar 命令就可以将多个目标文件打包为一个静态库。

jiaming@jiaming-pc:~/Documents/CSDN_Project$ cat test.c 
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a * b;
}
int div(int a, int b)
{return a / b;
}jiaming@jiaming-pc:~/Documents/CSDN_Project$ cat main.c
#include <stdio.h>int add(int, int);int main(void)
{int sum = 0;sum = add(1, 2);printf("sum=%d\n", sum);return 0;
}
jiaming@jiaming-pc:~/Documents/CSDN_Project$ gcc -c test.c # 将源文件 test.c 生成目标文件 test.o
jiaming@jiaming-pc:~/Documents/CSDN_Project$ ar -rcs libtest.a test.o # 使用 ar 命令将多个目标文件打包成 libtest.a
jiaming@jiaming-pc:~/Documents/CSDN_Project$ gcc main.c -L. -ltest # 指定需要链接的静态库及其所在的路径,库的名字 test
jiaming@jiaming-pc:~/Documents/CSDN_Project$ ./a.out 
sum=3

ar 命令:

  • -c:禁止在创建库时产生的正常消息
  • -r:如果指定的文件已经存在则替换
  • -s:无论库是否更新都强制重新生成新的符号表
  • -d:从库中删除指定的文件
  • -o:对压缩文档成员进行排序
  • -q:向库中追加指定文件
  • -t:打印库中的目标文件
  • -x:解压库中的目标文件

编译器是以源文件为单位进行编译程序的,链接器在链接过程中逐个对目标文件进行分解组装,这样会产生一个问题:如果在一个源文件中定义了 100 个函数,而只使用了其中一个,那么链接器在链接时也会把这 100 个函数逇代码指令全部组装到可执行文件中,这会让最终生成的可执行文件体积大大增加。

jiaming@jiaming-pc:~/Documents/CSDN_Project$ readelf -s a.out Symbol table '.symtab' contains 70 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name···50: 000000000000118b    24 FUNC    GLOBAL DEFAULT   16 add···53: 00000000000011d0    23 FUNC    GLOBAL DEFAULT   16 div···64: 0000000000001149    66 FUNC    GLOBAL DEFAULT   16 main65: 00000000000011b9    23 FUNC    GLOBAL DEFAULT   16 mul···68: 00000000000011a3    22 FUNC    GLOBAL DEFAULT   16 sub···

解决这个问题的办法是每一个函数均由一个独立的 C 程序实现,然后将多个文件(.o)打包即可(libtest.a)。C 标准库就是这么实现的,printf 函数由 printf.c 实现。如果只调用了一个 printf 函数,则链接器只是将 pritnf() 函数的目标文件链接到可执行文件中即可。

静态链接还会产生另外一个问题,如 C 标准库里 printf() 函数,可能多个程序都调用了它,链接器在链接时就要将 printf 的指令添加到多个可执行文件中。在一个多任务环境中,当多个进程并发运行时,内存中有大量重复的 printf 指令代码,很浪费内存资源。

解决办法是动态链接机制!

相关文章:

静态链接(7/13)

在一个软件项目中&#xff0c;为了完成特定功能&#xff0c;除了自定义函数&#xff0c;还可以使用别人已经封装好的函数库&#xff0c;如 C 函数库。库函数的使用避免了重复“造笼子”的重复工作&#xff0c;提高了代码复用率&#xff0c;大大减轻了软件开发的工作量。 库分为…...

jvs-rules API数据源配置说明(含配置APIdemo视频)

在JVS中&#xff0c;多数据源支持多种形态的数据接入&#xff0c;其中API是企业生产过程中常见的数据形态。使用数据源的集成配置&#xff0c;以统一的方式管理和集成多个API的数据。这些平台通常提供各种数据转换和处理功能&#xff0c;使得从不同数据源获取和处理数据变得更加…...

爬虫来介绍ChromeF12 谷歌开发者工具 -Network

了解网页基础(HTML、CSS、JavaScript) 了解HTTP基本原理 了解JSON格式 了解Ajax请求 了解爬虫基本原理 (一)、Chrome开发者工具面板概述 Elements 查找网页源代码HTML中的任一元素,手动修改任一元素的属性和样式且能实时在浏览器里面得到反馈。 比如我们在Event Listener…...

[足式机器人]Part4 机械设计 Ch00/01 绪论+机器结构组成与连接 ——【课程笔记】

本文仅供学习使用 本文参考&#xff1a; 《机械设计》 王德伦 马雅丽课件与日常作业可登录网址 http://edu.bell-lab.com/manage/#/login&#xff0c;选择观摩登录&#xff0c;查看2023机械设计2。 机械设计-Ch00Ch01——绪论机器结构组成与连接 Ch00-绪论0.1 何为机械设计——…...

Android isLoggable定制属于自己的log

Android原生自带的 android.util.Log&#xff0c;其中有一个 isLoggable 方法的运用 /** * Checks to see whether or not a log for the specified tag is loggable at the specified level.** The default level of any tag is set to INFO. This means that any level abov…...

【Spring Boot】构建RESTful服务 — 使用Swagger生成Web API文档

使用Swagger生成Web API文档 高质量的API文档在系统开发的过程中非常重要。本节介绍什么是Swagger&#xff0c;如何在Spring Boot项目中集成Swagger构建RESTful API文档&#xff0c;以及为Swagger配置Token等通用参数。 1.什么是Swagger Swagger是一个规范和完整的框架&…...

【实战】 九、深入React 状态管理与Redux机制(五) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二十)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…...

PHP傻瓜也能搭建自己框架

PHP最简单自定义自己的框架&#xff08;一&#xff09; PHP最简单自定义自己的框架创建目录结构&#xff08;二&#xff09; PHP最简单自定义自己的框架定义常量自动生成目录&#xff08;三&#xff09; PHP最简单自定义自己的框架控制器自动加载运行&#xff08;四&#xf…...

为什么商业基础软件需要开源

Bytebase 本身是一家商业软件公司&#xff0c;而作为最核心资产的代码从 Day 0 却是开源的。同时我们还是 star-history.com 的运营者&#xff0c;大家在各种开源渠道会看到它生成的图&#xff1a; 一直以来&#xff0c;常会被别人问起的一个问题&#xff0c;就是为什么 Byteba…...

【自用】云服务器 使用 docker 搭建 HomeAssistant + MQTT 物联网平台

总览 1.搭建流程概述 2.准备工作 3.开始搭建&#xff01; 4.总结 如果想看 ESP32 或其他使用 MicroPython 编程的单片机如何连接到该云服务器&#xff0c;实现 HomeAssistant 控制 单片机的内容&#xff0c;请看我这篇博客的下一篇。 一、搭建流程概述 0.总体流程 我们需要…...

ABAP: SQL 多值查询

基础查数据 问题举例&#xff1a;例如查物料类型为ZFRT、ZROH和ZRSA的物料编码。 1、直接查询&#xff0c;三种不同类型的物料类型是或的关系。 SELECT DISTINCT ma~matnr ma~mtartFROM mara AS maINNER JOIN mbewh AS mbON ma~matnr mb~matnrINTO CORRESPONDING FIELDS OF…...

分布式学习最佳实践:从分布式系统的特征开始

正文   在延伸feature&#xff08;分布式系统需要考虑的特性&#xff09;的时候&#xff0c;我逐渐明白&#xff0c;这是因为要满足这些feature&#xff0c;才设计了很多协议与算法&#xff0c;也提出了一些理论。比如说&#xff0c;这是因为要解决去中心化副本的一致性问题&…...

第三章 图论 No.8最近公共祖先lca, tarjan与次小生成树

文章目录 lcaTarjan板子题&#xff1a;1172. 祖孙询问lca或tarjan&#xff1a;1171. 距离356. 次小生成树352. 闇の連鎖 lca O ( m l o g n ) O(mlogn) O(mlogn)&#xff0c;n为节点数量&#xff0c;m为询问次数&#xff0c;lca是一种在线处理询问的算法 自己也是自己的祖先 倍…...

[Kubernetes]Kubeflow Pipelines - 基本介绍与安装方法

1. 背景 近些年来&#xff0c;人工智能技术在自然语言处理、视觉图像和自动驾驶方面都取得不小的成就&#xff0c;无论是工业界还是学术界大家都在惊叹一个又一个的模型设计。但是对于真正做过算法工程落地的同学&#xff0c;在惊叹这些模型的同时&#xff0c;更多的是在忧虑如…...

Sui网络的稳定性和高性能

Sui的最初的协议开发者设计了可扩展的网络&#xff0c;通过水平扩展的方式来保持可负担得起的gas费用。其他区块链与之相比&#xff0c;则使用稀缺性和交易成本来控制网络活动。 Sui主网上线前90天的数据指标证明了这一设计概念&#xff0c;在保持100&#xff05;正常运行的同…...

RabbitMQ 安装教程

RabbitMQ 安装教程 特殊说明 因为RabbitMQ基于Erlang开发&#xff0c;所以安装时需要先安装Erlang RabbitMQ和Erlang版本对应关系 查看地址&#xff1a;www.rabbitmq.com/which-erlan… 环境选择 Erlang: 23.3及以上 RabbitMQ: 3.10.1Windows 安装 1. 安装Erlang 下载地…...

STM32F429IGT6使用CubeMX配置GPIO点亮LED灯

1、硬件电路 2、设置RCC&#xff0c;选择高速外部时钟HSE,时钟设置为180MHz 3、配置GPIO引脚 4、生成工程配置 5、部分代码 6、实验现象...

DOM的节点操作+事件高级+DOM事件流+事件对象

一.节点操作 1.父节点: node.parentNode 得到的是离元素最近的父级节点 2.子节点: parentNode.childNodes 所有的子节点 包含元素节点 文本节点等等parentNode.children (非标准) 获取所有的子元素节点,实际开发常用 parentNode.firstChild 获取…...

云端剪切板,让你的数据同步无界

云端剪切板&#xff0c;让你的数据同步无界&#xff01; 每个人都应该保护自己的数据&#xff0c;同时使它易于访问和共享。这就是我们的云剪切板网站诞生的原因&#xff01;无论你在哪里&#xff0c;只要登录我们的网站&#xff0c;就可以随时随地使用你的剪切板数据。 你可…...

Location匹配与Rewrite重写

一、常见的Nginx正则表达式 ^ &#xff1a;匹配输入字符串的起始位置 $ &#xff1a;匹配输入字符串的结束位置 * &#xff1a;匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”&#xff1a;匹配前面的字符一次或多次。如“ol”能匹配“ol”及“oll”、“oll…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...