Linux使用第三方库链接的使用方式——静态式

news2024/9/21 1:58:35

 目录

二.第三方库为静态库时:

       方法1:  两个窗口去分别模拟两个窗口公司A(客户端),公司B(服务端)的视角案例实现:

        

       方法2——优化:该方法在上述方法1的第10步后开始进行:

这里强调一个问题:


今天我们来学习将第三方库作为动静态库去链接生成可执行文件的使用方式。

        之前我发过一篇关于使用动静态链接生成可执行文件的文章,里面简单的介绍了一下动静态链接的指令实现和动静态库的区别认识,有兴趣的伙伴们可以看看。

 Linux——gcc/g++编译器_橙予清的zzz~的博客-CSDN博客https://blog.csdn.net/weixin_69283129/article/details/130820057?spm=1001.2014.3001.5501        有了上面对动静态库基本知识的铺垫,接下来我将详细说明一个问题:当我们在写好一个源.c/cpp文件时,该如何使用第三方库的多种方式。

        首先,我先来写两个简单类型的头文件和函数实现,用于测试:

        如上,我写了加法和减法的俩个函数实现。

        然后我在测试main.c文件中包含了这俩函数的头文件,以便于使用Add和Sub函数。

然后就是对这些.c文件进行汇编链接,生成可执行文件:

 

执行结果:

        如上,这是我们一般情况下自产自销的写出文件后,汇编链接形成可执行文件。但若是在公司企业的话,就不一样了。

        举个例子公司A将某某项目外包给了公司B,该公司的程序员只写出了main.c文件,将指定要求的多个函数交给公司B去实现。公司B实现好后,将这些函数的.o文件和.h文件打包给了公司A,公司A的程序员收到后,立即将main.c文件汇编链接公司B的函数实现,完成了项目。 

         这里有几个问题需要解答一下:

        1.函数的生成也是从.c形式开始,一步步进行预处理成为.i文件---->编译成为.s文件---->汇编成为.o重定向二进制目标文件。而我们写的这些.c文件就是经过这三步形成.o类型文件,最终将这些.o文件链接起来生成.exe可执行文件(这是对于Windows系统来说的,因为Windows系统很重视文件的后缀类型,而对于Linux系统来说,文件后缀不重要)。

       

       

        2.为什么公司B在打包时只给了公司A函数的.o目标文件和.h头文件,却唯独不给函数的.c文件呢?

        因为外面做函数的公司不愿给客户源代码!!!对方不想让客户知道方法底层的实现,若是客户知道了底层的实现,就会掌握相应的技术方法和原理,这对做函数的公司来说是得不偿失的!所以只给出.o类型文件有两种原因:

        a.是为了增加安全性,因为给客户.o二进制目标文件,客户也无法破译出底层实现的原理,.o文件中全是二进制数据——打开是一堆乱码,没法用!

        b.客户只需要将自己的main.c文件生成.o文件,直接将对方提供的.o文件进行链接即可生成可执行文件。

        3. .h文件很重要,缺少了.h文件,那些函数就无法使用,也无法生成.o文件。所以我们必须同时拥有.o目标文件和.h头文件才能完成main.c的链接生成.exe文件

 

但假如项目是个几万行的代码,且公司B给提供的.o/.h文件有数百个呢,那么我们在链接的时候是不是得一个一个的输入这些文件进行链接,那不得累死吗?

        这时静态库的作用就体现出来了!案例的整个步骤如下:对方公司将提供给我们的所有.o文件和h文件也各自集合起来,打成一个压缩包(zip或者tgz形式的)——库文件,然后发布出去,我们在接收后需要进行解压然后获取,直接使用gcc指令链接即可。

         强调一下:我们平常使用gcc编译器写的C代码,都需要#include<stdio.h>,里面写的printf、return 0;等语句函数都是使用系统自带的libC库方法和库头文件,所以我们不需要主动进行链接,但若是使用第三方库却不行,需要主动链接。——为后面案例的第11步埋下了伏笔!

 我们就是依赖这两个东西才能写成功C代码并运行。


二.第三方库为静态库时:

       方法1:  两个窗口去分别模拟两个窗口公司A(客户端),公司B(服务端)的视角案例实现:

        

        1.首先,先创建makefile自动化构建工具,以遍书写指令:

        2.其次,这是客户端的目录视角,该目录只有客户自己写的main.c的文件,他正在等待着公司B的函数文件传来:

        3.以下便是服务端的目录执行视角,公司B已经做好了客户需要的函数实现.c文件和头文件:

 

提前插播一条指令:生成静态库文件的指令

        ar -rc (生成的静态库文件名) (所要依赖的文件名)

        解析:ar代表archive,意为把…存档; 把…归档。

        4.然后,公司B将.c函数文件全都生成为.o文件,使用ar -rc将相应的.o文件全都集合生成静态库文件lib_math.a:

5.使用makefile自动化工具创建指令:

 output的指令解析:通过创建一个递归目录,将.a文件和.h文件放在相应的位置中——打包。

6.执行打包命令:

 7.将打包好的文件进行压缩:tar czf指令为压缩指令:

         之后,公司B就可以将做好的安装包发送到客户的邮箱中,客户便可以从中获取到里面的库文件和头文件。

        

 8.以下便是客户端的目录视角,客户下载安装包——其实下载的本质就是拷贝!

 9.客户开始解压安装包:tar xzf为解压指令:

 10.查看是否成功安装:

 从图片上看,表明成功安装。

 11.下载完后,便可以开始链接生成可执行文件了:

上图错误分析:在链接过程中发现链接错误,说系统没有找到MyAdd.h。不对啊,客户心想:我不是把安装包下载好并和main.c放在同一目录下了吗,为什么编译器说没有找到?

        

        因为在案例说明前面埋下的那个伏笔!这是第三方库,需要主动链接头文件的所在路径!

        解决方法如下:在后面加上:-I 头文件的路径

        上图错误分析:但是链接后发现头文件的问题解决了,又出现了不认识第三方库函数的问题。这表明不仅第三方的头文件需要链接,而且第三方的库文件也需要链接!

        解决方法如下:在后面加上:-L 库文件的路径 

                                  在后面加上:-l 库文件的名称

       

        为什么还要加上库文件的名称?gcc在编译的过程中只会从被指定的路径中寻找系统自带的头文件和库文件,而第三方的库文件它压根不会去主动找,只能由你提示告诉编译器相关的路径和名称!

        上图错误解决方法:-l链接方式有问题,需要去除静态库文件libmy_math.a的前缀lib和后缀.a!

        如下:

 最终链接运行成功!

以上就是使用静态库作为第三方库的一种方法,看起来是相当的复杂啊~,这是因为我们没有将包中的头文件和库文件放在系统指定的路径下,所以需要增加很多繁琐的步骤。

方法2——优化:该方法在上述方法1的第10步后开始进行:

11、将解压后的目录文件进行拷贝转移到gcc编译器默认寻找的路径下:

gcc编译器的默认寻找头文件、库文件路径:

        通过上图步骤,我们已将库文件和头文件成功的安装到了gcc指定的路径下,这样做的好处就在于不用像方法1那种主动链接,gcc会自动找到! 

12.最后一步: 

 也得要去链接并且标明去掉静态库文件的前缀和后缀。然后就大功告成了!!!


这里强调一个问题:

       知识拓展:

         file指令该指令可以识别文件类型的命令,通过查看文件的头部信息来获取文件类型。它不支持扩展名。同时,file命令还可以列出文件辨识结果、详细显示指令执行过程、文件名中的文件类型、mime类型的字符串等。 

        我们使用file指令去识别这个生成的可执行文件Myfile.exe时,发现它是dynamically linked(动态链接的形式),为什么?我们使用的不是静态库吗?静态库应该是使用静态链接进行啊!

       1. gcc编译器是专门用来写C语言的,它只认识指定路径下的库文件,我们写的静态库文件虽然也被识别到了,但是我们的代码中还用到了系统提供的<stdio.h>等动态库,所以该可执行文件依赖的就不仅仅是第三方库一个库了,而且系统提供的默认情况下是动态库,所以依赖的只要有一个动态库,文件显示出来的就是动态链接!

        2.除非该文件依赖的全是静态库,文件才会显示静态链接!!!

        3.gcc默认是动态链接的。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/690725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux上虚拟机vmware-workstation离线安装详细教程

linux上虚拟机vmware-workstation详细教程 一、VMWare基本介绍二、VMWare下载2.1 查看本地系统信息2.2 选择及下载合适的版本 三、VMWare安装3.1 安装依赖库3.2 vmware安装3.3 验证安装3.4 异常及解决方案3.4.1 Failed to start SYSV3.4.2 GLib does not have GSettings suppor…

编程:“上学时如果遇到自己,我会更早的成为我?”

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 如果当年我遇到自己&#xff0c;我会更早的成为我&#xff1f; 你觉得一瞬间的技术能力提升&#xff0c;是必须经历过过吃苦或者…

Python安装教程(初学者很实用)

一、Python环境搭建 1、下载Python 进入Python官网下载安装包 https://www.python.org/ 2、选择合适的版本&#xff0c;点击下载 3、安装Python 双击安装软件 等待安装完成 出现【setup was successful】&#xff0c;表示安装成功 4、检验是否安装成功 通过【winr】调出…

llama.cpp LLM模型 windows cpu安装部署

参考&#xff1a; https://www.listera.top/ji-xu-zhe-teng-xia-chinese-llama-alpaca/ https://blog.csdn.net/qq_38238956/article/details/130113599 cmake windows安装参考&#xff1a;https://blog.csdn.net/weixin_42357472/article/details/131314105 llama.cpp下载编…

DAY30:回溯算法(五)分割回文串+复原IP地址(注意复盘,经典的分割子集问题)

文章目录 131.分割回文串思路伪代码重要问题1&#xff1a;如何通过startIndex判断已经切到结束了重要问题2&#xff1a;为什么[startIndex,i]能够表示当前遍历的子串substr的用法 std::string的成员函数std::string完整版debug测试**Line 4: Char 27: error: expected unqualif…

MySQL------事务并发问题和解决办法

一、事务并发问题 1. 脏读 含义&#xff1a;在事务过程中&#xff0c;A事务还未提交&#xff0c;B事务就读到了A事务未提交的数据。 一个事务正在对一条记录做修、改&#xff0c;在这个事务完成并提交前&#xff0c;这条记录的数据就处于不一致状态&#xff1b;这时&#xff0c…

PHP 文心千帆API接口对接

一&#xff1a;API 调用流程简介 创建一个智能云应用。根据实际需求创建智能云应用。创建成功后&#xff0c;获取AppID、API Key、Secret Key 等信息。API 授权。对应用的 AppID 进行授权。获取接口访问凭证 access_token 。根据第1步获取的 API Key 和 Secret Key &#xff0c…

外观模式(Facade)

定义 外观是一种结构型设计模式&#xff0c;能为程序库、框架或其他复杂类提供一个简单的接口。 前言 1. 问题 假设你必须在代码中使用某个复杂的库或框架中的众多对象。正常情况下&#xff0c;你需要负责所有对象的初始化工作、管理其依赖关系并按正确的顺序执行方法等。 …

centos 手动下载包安装elasticsearch8.7.0, 并设置密码访问

访问下载网站 Elasticsearch 8.7.0 | Elastic 进入centos , 创建目录es mkdir /opt/es cd /opt/es wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.7.0-linux-x86_64.tar.gz 3、解压目录 es870 tar -zxvf elasticsearch-8.7.0-linux-x86_64.tar…

二叉树的堂兄弟节点——深度优先搜索+广度优先搜索

二叉树的堂兄弟节点 题目描述 在二叉树中&#xff0c;根节点位于深度 0 处&#xff0c;每个深度为 k 的节点的子节点位于深度 k1 处。 如果二叉树的两个节点深度相同&#xff0c;但 父节点不同 &#xff0c;则它们是一对堂兄弟节点。 我们给出了具有唯一值的二叉树的根节点 …

实现分布式事务的新标杆:RocketMQ的全面解析与应用指南

在分布式系统中&#xff0c;实现事务的一致性和可靠性是一项重要的挑战。本文将详细介绍如何利用 RocketMQ 的半消息机制来实现分布式事务&#xff0c;并提供具体的代码示例和最佳实践。 1. 引言 在分布式系统中&#xff0c;事务处理是一项复杂而关键的任务。传统的 ACID 事务…

基于SpringCloud微服务毕业论文管理系统设计与实现

一、概述 1.1 课题背景及意义 随着学校不断扩大和学生人数的猛增,关于各类教学信息也越来越多。毕业论文的管理也成为了不可避免的一道关卡,学生需要及时获取论文相关进度,学校的管理者要求能方便对论文进行处理。基于这些需求,开发一个实用的微服务管理系统,以满足双方…

13-使用调度框架quartz,为系统增加定时调度功能

1 、创建后端模块batch 1.1、创建maven项目 1.2、pom.xml文件中导入依赖 <dependencies><!-- common--><dependency><groupId>com.wei</groupId><artifactId>common</artifactId></dependency><!-- 热部署…

电磁兼容常用测量单位及转换关系 dB、dBm、dBw、dBμV、dBmV、dBV、dBA等单位介绍

目 录 摘要分贝简介分贝在EMC测试中电磁兼容常用测量单位常用线性单位的对数转换单位间转换基于50Ω额定阻抗的电压、电流和功率单位间的换算基于50Ω额定阻抗的场强单位间的换算 单位换算的应用参考文献总结 摘要 为获得更大的相对幅度显示范围&#xff0c;电磁兼容测试常使用…

Graalvm Native Image 元数据适配

Graalvm Native Image 元数据适配 本文章主要叙述在 Java 应用适配 Graalvm Native Image 中的步骤和遇到的一些问题&#xff01;因为 Graalvm 官方文档相关概念叙述过于简单。基本靠问才能知道些许有用信息。所以写此文章。 关于 Graalvm 基础知识的相关学习&#xff0c;可以…

部署 LAMP平台Linux,Apache,MySQL ,PHP源码编译安装

目录 一、.LAMP简介与概述 1.LAMP平台概述 2. 构建LAMP平台顺序 3. 编译安装的优点 4. 各组件作用 5. 数据流向 二、编译安装Apache httpd服务 1.关闭防火墙&#xff0c;将安装Apache所需软件包传到/opt目录下 2.安装环境依赖包 3.配置软件模块 4.编译及安装 5.优…

chatgpt赋能python:Python获取父类:探究继承关系的技巧

Python获取父类&#xff1a;探究继承关系的技巧 Python是一种高级编程语言&#xff0c;它被广泛用于Web开发、数据分析、人工智能等领域。Python的面向对象编程是其特色之一。在面向对象编程中&#xff0c;我们经常需要使用继承关系来定义不同类之间的关系。在这篇文章中&…

小程序学习(一):基本知识点笔记

1.小程序与普通网页开发的区别 1.运行环境不同 网页运行在浏览器环境中 小程序运行在微信环境中 2.API不同 由于运行环境的不同,小程序无法调用DOM和BOM的API。 但是,小程序中可以调用微信环境提供的各种API,例如:地理定位、扫码、支付... 3.开发模式不同 网页的开发模式:浏览器…

C语言笔记-4 输入输出

目录 输入输出简单举例scanf()getchar()putchar()puts()gets() 标准文件%d 格式化输出整数%f 格式化输出浮点型数据 getchar() & putchar() 函数gets() & puts() 函数scanf() 和 printf() 函数 输入输出 简单举例 scanf() 空格、回车也是字符&#xff0c;下面情况也…

APP盲盒系统开发前端后台详细功能讲解

一、栏目 功能 说明 登录注册 注册 输入手j号&#xff0c;获取验zm&#xff0c;输入密m 密码登录 手机号密码 忘记密码 输入手j号&#xff0c;获取y证m&#xff0c;输入新m码 底部导航 开盲盒、寄售中心、商城、个人中心 开盲盒 显示盲盒 可滑动更换其他盲盒 立即开盒 点…