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

Linux 链接器如何使用静态库来解析引用

文章目录

  • 通过进行代码实践
  • 静态库在编译时被链接到可执行文件中的基本原理
    • 原理总结
  • QA:
    • .obj文件是什么?

通过进行代码实践

链接器在解析引用时,可以使用静态库来满足对未定义符号的引用。以下是使用静态库的一般步骤:

  1. 编写代码: 首先,写源代码文件,其中包含对某个库中函数或变量的引用。例如,有一个文件 main.c,其中包含对库函数的调用。

    // main.c
    #include <stdio.h>// 外部函数声明,该函数定义在库中
    extern void libraryFunction();int main() {printf("Calling library function...\n");libraryFunction();return 0;
    }
    

库源码:

//mylibrary.c
#include <stdio.h>
void libraryFunction(){printf("libraryFunction");
}
  1. 编译对象文件: 编译源文件以生成对象文件。这将创建一个与源文件相对应的 .o.obj 文件。

构建调用函数的目标文件:

gcc -c main.c -o main.o

构建库的目标文件:

gcc -c mylibrary.c -o mylibrary.o
  1. 创建静态库: 使用编译器工具(通常是 ar)创建静态库。静态库文件的命名通常以 lib 开头,以 .a 结尾。

    ar rcs libmylibrary.a mylibrary.o
    

    上述命令将 mylibrary.o 文件打包成静态库 libmylibrary.a

  2. 链接应用程序: 将生成的对象文件与静态库链接起来,以生成可执行文件。

    gcc main.o -o myapp -L. -lmylibrary
    
    • -L.:告诉链接器在当前目录中查找库文件。
    • -lmylibrary:指定链接的库,去掉前缀 lib 和文件扩展名,链接器会自动查找 libmylibrary.a
  3. 运行应用程序: 最后,运行生成的可执行文件。

    ./myapp
    

运行结果:
在这里插入图片描述
目录:
在这里插入图片描述

通过这个过程,链接器将在静态库中查找并解析在源代码中引用但未定义的符号,从而完成对库函数的引用。需要确保静态库和可执行文件在相同的目录中,或者通过适当的路径设置使得链接器能够找到静态库。

静态库在编译时被链接到可执行文件中的基本原理

链接器使用静态库解析引用的过程可以分为几个基本步骤,从原理的角度来理解:

  1. 创建静态库: 静态库是由一组目标文件(.o.obj 文件)打包而成的。这些目标文件包含了一些编译好的代码和数据,可能是一些函数的实现和相关的数据结构。

  2. 引用与定义分离: 在源代码中,当你使用 extern 声明一个函数或变量时,它表示这个符号是在其他地方定义的,而当前文件中只是引用了它,还没有具体的实现。
    链接: extern关键字解析

    // 在一个源文件中的引用
    extern void someFunction();
    
  3. 编译阶段: 源代码通过编译器生成目标文件。在编译时,编译器并不关心 extern 声明的符号在哪里定义,而只是生成对这些符号的引用。

  4. 创建可执行文件: 当所有的源文件都被编译成目标文件后,链接器负责将这些目标文件合并成一个可执行文件。在这个过程中,如果某个符号在当前目标文件中没有定义,而只是声明(使用了 extern),链接器会去查找其他的目标文件或静态库来找到符号的定义。

  5. 静态库链接: 当链接器在链接时遇到 extern 声明的符号时,它会查找静态库中的目标文件,然后将符号与静态库中对应目标文件的定义关联起来。这个过程实际上是将静态库中的目标文件提取出来,合并到最终的可执行文件中。

  6. 生成可执行文件: 最终,链接器生成一个包含所有目标文件和静态库中代码的可执行文件。这个可执行文件中包含了所有符号的定义,使得程序能够正确运行。

原理总结

链接器通过在链接过程中查找静态库中的目标文件,将其合并到可执行文件中,从而解析了对静态库中定义的函数和变量的引用。这样,程序就能够在运行时访问静态库中的功能。这也是静态库在编译时被链接到可执行文件中的基本原理。

QA:

.obj文件是什么?

.obj 文件是一种目标文件(Object File),它是源代码编译后生成的中间文件,包含了汇编或机器代码、符号表以及其他一些用于链接的信息。这个文件是编译过程中的一个阶段,通常在源代码被编译成机器代码之前。

主要的编译过程包括以下步骤:

  1. 预处理(Preprocessing): 展开宏、包含头文件等。

  2. 编译(Compilation): 将预处理后的源代码翻译成汇编语言或机器代码。

  3. 汇编(Assembly): 将汇编代码转化成机器代码,并生成目标文件(.obj 文件)。

  4. 链接(Linking): 将所有目标文件和可能的库链接在一起,生成最终的可执行文件。

.obj 文件是编译器生成的中间产物,其中包含了编译阶段产生的汇编或机器代码,以及与链接有关的一些元数据,比如符号表(用于记录变量和函数的信息)、重定位信息(用于指示链接器在最终的可执行文件中放置代码的位置)等。

在编译过程中,.obj 文件用于保存每个源文件的编译结果,这样链接器可以在链接阶段将它们组合起来,生成最终的可执行文件。在不同的操作系统和体系结构中,目标文件的格式可能有所不同。在Windows平台上,常见的目标文件格式是 .obj,而在类Unix系统上,通常使用的是 .o 文件。

相关文章:

Linux 链接器如何使用静态库来解析引用

文章目录 通过进行代码实践静态库在编译时被链接到可执行文件中的基本原理原理总结 QA:.obj文件是什么? 通过进行代码实践 链接器在解析引用时&#xff0c;可以使用静态库来满足对未定义符号的引用。以下是使用静态库的一般步骤&#xff1a; 编写代码&#xff1a; 首先&#…...

vue实现滑动验证

效果图&#xff1a; 源码地址&#xff1a;github文档地址&#xff1a; https://github.com/monoplasty/vue-monoplasty-slide-verify 使用步骤&#xff1a;1&#xff0c;安装插件&#xff1a; npm install --save vue-monoplasty-slide-verify 在main.js中使用一下&#xff…...

***Cpolar配置外网访问和Dashy

Dashy是一个开源的自托管的导航页配置服务,具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起,形成自己的导航页。一款功能超强大,颜值爆表的可定制专属导航页工具 结合cpolar内网工具,我们实现无需部署到公网服务器…...

Rancher中使用promtail+loki+grafna收集k8s日志并展示

Rancher中使用promtail+loki+grafna收集k8s日志并展示 根据应用需求和日志数量级别选择对应的日志收集、过滤和展示方式,当日志量不太大,又想简单集中管理查看日志时,可使用promtail+loki+grafna的方式。本文找那个loki和grafana外置在了k8s集群之外。 1、添加Chart Repo …...

modelbox线程爆满宕机bug

序 该bug的解决需要特别感谢张同学。有了大佬的帮助&#xff0c;这个bug才得以解决。 问题现象 modelbox可以进行模型推理&#xff0c;但压测一段时间后&#xff0c;modelbox会宕机&#xff0c;并发生段错误。 “libgomp: Thread creation failed: Resource temporarily una…...

KUKA机器人如何在程序中编辑等待时间?

KUKA机器人如何在程序中编辑等待时间&#xff1f; 如下图所示&#xff0c;如何实现在P1点和P2点之间等待设定的时间&#xff1f; 如下图所示&#xff0c;可以直接输入wait sec 2&#xff08;等待2秒&#xff09;&#xff0c; 如下图所示&#xff0c;再次选中该程序后&#…...

MQ入门简介

当年入门MQ时跟着尚硅谷RabbitMQ视频学习所做的一些笔记&#xff0c;现在上传方便有需要小伙伴查看 一&#xff1a;MQ的相关概念 1.什么是MQ MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内…...

如何正确使用缓存来提升系统性能

文章目录 引言什么时候适合加缓存&#xff1f;示例1示例2&#xff1a;示例3&#xff1a; 缓存应该怎么配置&#xff1f;数据分布**缓存容量大小&#xff1a;**数据淘汰策略 缓存的副作用总结 引言 在上一篇文章IO密集型服务提升性能的三种方法中&#xff0c;我们提到了三种优化…...

IDEA中Terminal配置为bash

简介 我们日常命令行都是使用Linux的bash指令&#xff0c;但是我们的开发基本都是基于Windows上的IDEA进行开发的&#xff0c;对此我们可以通过将IDEA将终端Terminal改为git bash自带的bash.exe解决问题。 配置步骤 安装GIT 这步无需多说了&#xff0c;读者可自行到官网下载…...

C# 字符串格式化

写在前面 在日常编程中&#xff0c;经常需要对字符串进行格式化操作&#xff0c;以便呈现为不同的格式&#xff0c;满足各种各样的显示需求&#xff0c;C#的字符串格式化参数是非常丰富的&#xff0c;这里做个简单的列举&#xff0c;以供后续参考和延伸。 代码实现 var curr…...

基于亚马逊云科技新功能:Amazon SageMaker Canvas无代码机器学习—以构建货物的交付状态检测模型实战为例深度剖析以突显其特性

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在亚马逊云科技开发者社区、 知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道。 目录 &#x1f680;一. Amazon SageMaker &#x1f50e;1.1 新功能发布&#xff1a;A…...

基于Spring Boot、Mybatis、Redis和Layui的企业电子招投标系统源码实现与立项流程

招投标管理系统是一款适用于招标代理、政府采购、企业采购和工程交易等领域的企业级应用平台。该平台以项目为主线&#xff0c;从项目立项到项目归档&#xff0c;实现了全流程的高效沟通和协作。通过该平台&#xff0c;用户可以实时共享项目数据信息&#xff0c;实现规范化管理…...

electron这样使用更安全

背景&#xff1a; electron大家平时为了方便使用&#xff0c;或是一些网上demo的引导&#xff0c;会让渲染进程的业务界面支持直接使用nodejs&#xff0c;这种开发方式有一定的安全隐患&#xff0c;如果业务界面因为xss之类的漏洞被注入其他代码&#xff0c;危害非常大&#x…...

DPDK多进程之间的通信

文章目录 前言本机DPDK IPC API介绍demo演示 前言 DPDK的主进程和辅助进程之间共享大页内存。关于DPDK多进程的支持文档介绍见&#xff1a;47. 多进程支持。 本文介绍本机DPDK的主进程和辅助进程之间交换短消息的API的使用。 前置要求&#xff1a;DPDK-Hello-World示例应用程…...

Python文本信息解析:从基础到高级实战‘[pp]]‘[

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 Python文本信息解析&#xff1a;从基础到高级实战&#xff0c;全文3600字&#xff0c;阅读大约10分钟。 文本处理是Python编程中一项不可或缺的技能&#xff0c;覆盖了广泛的…...

c语言多线程队列实现

为了用c语言实现队列进行多线程通信&#xff0c;用于实现一个状态机。 下面是实现过程 1.实现多线程队列入栈和出栈&#xff0c;不加锁 发送线程发送字符1&#xff0c;接收线程接收字符并打印。 多线程没有加锁&#xff0c;会有危险 #include "stdio.h" #include …...

一分钟带你了解电容

电容器中的电容究竟是怎么定义的&#xff1f; 一个电容器&#xff0c;如果带1库的电量时两级间的电势差是1伏&#xff0c;这个电容器的电容就是1法拉&#xff0c;即&#xff1a;CQ/U 。但电容的大小不是由Q&#xff08;带电量&#xff09;或U&#xff08;电压&#xff09;决定…...

SQLAlchemy 第一篇

安装SQLAlchemy pip install SQLAlchemy查看当前版本 # 查看当前版本import sqlalchemyprint(sqlalchemy.__version__)2.0.23创建数据库连接 此处我们以pymysql为mysql的数据库驱动 安装pymysql pip install pymysqlfrom sqlalchemy import create_engine engine create_…...

Node.js模块化的基本概念和分类及使用方法

1.模块概念 模块&#xff1a;指解决一个复杂问题的时候&#xff0c;自顶向下逐层把系统划分成若干模块的过程。对于整个系统来讲&#xff0c;模块是可以组合、分解和更换的单元。 在编辑领域中的模块&#xff0c;就是遵守固定的规则&#xff0c;把一个大文件拆成独立并且相互…...

SpringBoot整合Lucene实现全文检索【详细步骤】【附源码】

笑小枫的专属目录 1. 项目背景2. 什么是Lucene3. 引入依赖&#xff0c;配置索引3.1 引入Lucene依赖和分词器依赖3.2 表结构和数据准备3.3 创建索引3.4 修改索引3.5删除索引 4. 数据检索4.1 基础搜索4.2 一个关键词&#xff0c;在多个字段里面搜索4.3 搜索结果高亮显示4.4 分页检…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...