【c语言】gcc编译动态库静态库和使用说明

(1)linux和win下库后缀名

在WIN上封装为.dll(动),.lib(静)。

在LINUX上封装为.so(动),.a(静)

(2)动态库的封装和使用

示例1

源代码文件:fun.c、main.c

1.生成动态库(将fun.c生成动态库)

#生成func.o
#参数 -fPIC 表示生成与位置无关代码,执行完毕后生成一系列的 .o 文件
gcc func.c -o func.o -c -fPIC#生成libfunc.dll(windows动态库)
gcc func.o -shared -o libfunc.dll #生成libfunc.so(linux动态库)
gcc func.o -shared -o libfunc.so

2.编译可执行文件(在只有main.c和func动态库的情况下编译)

# 假设func动态库在当前目录下
# 生成可执行文件main
gcc main.c -o main -L . -l func 

3.运行可执行文件

先将动态库放到可执行文件的同级目录下
或者执行如下命令(linux环境时)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库所在目录路径然后执行可执行文件
./main

示例2

1.生成"与位置无关"的目标文件

gcc -fPIC a.c b.c c.c -c -I ../include

参数 -fPIC 表示生成与位置无关代码,执行完毕后生成一系列的 .o 文件

2.制作动态库

# linux
gcc -shared -o libmytest.so a.o b.o c.o# windows
gcc -shared -o libmytest.dll a.o b.o c.o

3.linux动态库使用

示例

[root@CentOS2 xxx]# ls
1.txt  add.h  libadd.so  main.c  temp  yyy.txt
[root@CentOS2 xxx]# gcc main.c -L./ -ladd -I./ -o test_so
[root@CentOS2 xxx]# ls
1.txt  add.h  libadd.so  main.c  temp  test_so  yyy.txt
[root@CentOS2 xxx]# pwd
/root/xxx
[root@CentOS2 xxx]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/xxx
[root@CentOS2 xxx]# ./test_so
1+2=3
[root@CentOS2 xxx]#

(3)gcc编译程序时找库说明

我们⽤gcc编译程序时,常常会⽤到“-I”(⼤写i),“-L”(⼤写l),“-l”(⼩写l)等参数,下面做个记录:例:

gcc -o hello hello1.c hello2.c hello3.c -I /home/hello/include -L /home/hello/lib -l world

这条命令运⾏后,会在当前⽂件夹下产⽣⼀个hello⽂件,这个⽂件就是可执⾏⽂件。在当前⽂件执⾏命令./hello,即可运⾏该⽂件。

  • -I /home/hello/include,表示将/home/hello/include⽬录作为第⼀个寻找源代码中引⼊的头⽂件的⽬录,寻找的顺序是:/home/hello/include –> /usr/include –> /usr/local/include, 也就是指定优先查找的⽬录,找不到的话查找默认⽬录。如果没有-I相关的指定,那么就是省略头⽂件位置默认为当前⽂件夹。
  • -L /home/hello/lib,表示将/home/hello/lib⽬录作为第⼀个寻找库⽂件的⽬录, 寻找的顺序 是:/home/hello/lib –> /lib –> /usr/lib –> /usr/local/lib,同上,也是指定优先查找的⽬ 录,如果省略就是指当前⽂件夹优先。"-L . "表示在当前⽬录找。
  • -l word, 表示寻找具体的动态链接库⽂件word.dll或者word.so,如果 在最后 再加上编译选项 static,表示寻找静态链接库⽂件,也就是word.lib或者word.a。

(4)静态库的封装和使用

示例1

源代码文件:fun.c、main.c

1.生成静态库(将fun.c生成静态库)

#生成func.o
gcc func.c -o func.o -c#生成libfunc.a (linux静态库)
ar -crv libfunc.a func.o  #生成libfunc.liib (windows静态库
ar -crv libfunc.lib func.o  

2.编译可执行文件(在只有main.c和func静态库的情况下编译)

# 假设func静态库在当前目录下,且没有func动态库
# 生成可执行文件main
gcc main.c -o main -L . -l func 

3.运行可执行文件

# 只要可执行文件时链接静态库生成的
# 不管当前目录有没有静态库,直接运行可执行文件即可
./main

示例2

1.生成.o文件

这里会生成a.o、b.o、c.o文件

gcc a.c b.c c.c -c -I ../include

2.将.o文件打包得到静态库文件

# 就是一个打包.o文件的过程,以libmytest.a为例# linux
ar rcs libmytest.a a.o b.o c.o # windows
ar rcs libmytest.lib a.o b.o c.o 

说明:

  • ar 工具不包含在gcc中
  • r --> 将文件插入静态库中
  • c --> 创建静态库,不管库是否存在
  • s --> 写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。

3.linux静态库使用

gcc + 源文件 + -L 静态库路径 + -l静态库名 + -I头文件目录 + -o 可执行文件名

#gcc + 源文件 + -L 静态库路径 + -l静态库名 + -I头文件目录 + -o 可执行文件名
gcc main.c -L./ -lmytest -I./ -o test或者#gcc + 源文件 + -I头文件目录 + libxxx.a + -o 可执行文件名
gcc main.c -I./ libmytest.a -o test

(5)动态库和静态库的使用区别 

静态库是必须要链接到执⾏⽂件中去的,⽽动态库是不需要链接到最后的执⾏⽂件中的,也就是说,对于最后的执⾏⽂件⽽⾔,如果是链接静态库生成的可执行文件,在运行可执行文件时,你是否删除静态库⽆所谓。但是,如果是链接动态库生成的可执行文件,⼀旦你删除了动态库,最后的可执⾏⽂件就玩不转了。

用动态库编译特点

1,库的代码不会编译进程序⾥⾯,所以动态库编译的程序⽐较⼩。

2,由动态库编译的程序依赖于系统的环境变量有没有此库⽂件,⽆则运⾏不了。

用静态库编译特点

 1,库的代码会编译进程序⾥⾯,所以静态库编译的程序⽐较⼤

 2,由静态库编译的程序不⽤依赖于系统的环境变量,所以环境变量有没有这个库⽂件,也 可以运⾏。

静态库使用优缺点

  • 优点:库被打包到可执行程序中,直接发布可执行程序即可使用
  • 缺点:静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。如果静态函数库改变了,那么你的程序必须重新编译。
  • 使用场合:在核心程序上使用,保证速度,可忽视空间。主流应用于80、90年代,现在很少用。

动态库使用优缺点

  • 机制:共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。
  • 优点:节省内存(共享)、易于更新(动态链接):停止运行程序 → 使用新库覆盖旧库(保证新旧库名称一致,接口一致) “接口”→ 重新启动程序
  • 缺点:延时绑定,速度略慢
  • 使用场合:对速度要求不是很强烈的地方都应使用动态库
  • 注意事项:动态库是否加载到内存,取决于程序是否运行。

(6)编译时指定动态库或者静态库编译

如果当前⽂件夹中既有动态库,也有静态库, 静态库与动态库同名的话(比如同时存在libfunc.a和libfunc.so),在编译时,默认会优先使⽤动态库进行编译。

gcc main.c -o main -L. -l ToolFunc

-L. -l ToolFunc会查找当前⽬录下的库,优先找动态库,若找到,则直接使⽤动态库进⾏编 译,而不使⽤静态库进⾏编译;若未找到动态库,则寻找静态库进行编译;若静态库也未找到,则提示报错。

如何强制使⽤静态库编译:如果在最后 再加上编译选项-static,表示寻找静态链接库⽂件。可强制编译时使⽤静态库,如果不使⽤这个参数,⽽静态库与动态库同名的话,会优 先使⽤动态库

gcc main.c -o main2  -L . -l ToolFunc -static


end

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

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

相关文章

戴尔g15删掉的数据怎么恢复?介绍几种常用方法

随着科技的发展,电脑已成为我们日常生活和工作中不可或缺的一部分。其中,戴尔G15作为一款高性能的笔记本电脑,受到了许多用户的青睐。然而,就像任何电子设备一样,戴尔G15也难免会遇到数据丢失的问题。因此,…

纳米体育数据足球数据接口: 指数数据包接口文档API示例⑦

纳米体育数据的数据接口通过JSON拉流方式获取200多个国家的体育赛事实时数据或历史数据的编程接口,无请求次数限制,可按需购买,接口稳定高效;覆盖项目包括足球、篮球、网球、电子竞技、奥运等专题、数据内容。 纳米数据API2.0版本…

【算法刷题】手撕LRU算法(原理、图解、核心思想)

文章目录 1.LRU算法1.1相关概念1.2图解举例1.3基于HashMap和双向链表实现1.3.1核心思想1.3.2代码解读1.3.3全部代码 1.LRU算法 1.1相关概念 LRU(Least Recently Used,最近最久未使用算法): 定义:根据页面调入内存后的…

python画图笔记

1. 直方图:Matplotlib 中如何同时绘制两个直方图? - 知乎 (zhihu.com) matplotlib可视化之直方图plt.hist()与密度图-CSDN博客

力扣练习题(2024/4/19)

1两个字符串的删除操作 给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 示例 1: 输入: word1 "sea", word2 "eat" 输出: 2 解释: 第一步将 "se…

(一)、SQL进阶——神奇的SQL

一、CASE表达式 1、CASE表达式概述 case表达式有简单case表达式和搜索case表达式两种写法 -- 简单case表达式 case sex when 1 then 男 when 0 then 女 else 其他 end -- 搜索case表达式 case when sex1 then 男 when sex1 then 男 else 其他 end 这两种写法执行的结…

跨平台手机号:微信手机号授权登录、微信授权登录双登录实现账户生态融合,新时代的身份密钥

小程序厂商的多样性体现在开发工具、服务领域、商业模式等多方面,各厂商凭借独特的技术优势、行业解决方案和市场策略,满足不同企业和用户需求。与此同时,随着移动互联网发展,手机号统一登录成为提升用户体验、简化登录流程的关键…

每日一篇 4.24(提前)

condemns :谴责 Claim:说法 malicious:恶意 curb:遏制 stabilization of xxx ties:xx关系稳定 launched its harshest attack to date on xxx:发起了迄今为止最严厉的攻击 suppressing:打压 favorable…

Go语言接口使用

底层值为 nil 的接口值 即便接口内的具体值为 nil,方法仍然会被 nil 接收者调用。 在一些语言中,这会触发一个空指针异常,但在 Go 中通常会写一些方法来优雅地处理它(如本例中的 M 方法)。 注意: 保存了 nil 具体值…

要养生也要时尚,益百分满足你的所有需求

要养生也要时尚,益百分满足你的所有需求 艾灸是个好东西,尤其是在近几年的时候,艾灸就像一阵浪潮席卷进了人们的日常生活之中,我们可以在街边看到大大小小的艾灸馆,有些评价比较高的艾灸馆门前甚至还排起了长长的队伍…

Unity3D 分块编辑小AStar地图详解

前言 A算法是一种经典的寻路算法,能够帮助游戏中的角色找到最短路径。在本文中,我们将介绍如何在Unity3D中使用分块编辑的方式创建一个小的A地图,并实现A*算法来实现角色的寻路。 对惹,这里有一个游戏开发交流小组,希…

FasterViT:英伟达提出分层注意力,构造高吞吐CNN-ViT混合网络 | ICLR 2024

论文设计了新的CNN-ViT混合神经网络FasterViT,重点关注计算机视觉应用的图像吞吐能力。FasterViT结合CNN的局部特征学习的特性和ViT的全局建模特性,引入分层注意力(HAT)方法在降低计算成本的同时增加窗口间的交互。在包括分类、对…

【InternLM 实战营第二期笔记】Lagent AgentLego 智能体应用搭建

理论知识 Lagent 是什么 Lagent 是一个轻量级开源智能体框架,旨在让用户可以高效地构建基于大语言模型的智能体。同时它也提供了一些典型工具以增强大语言模型的能力。 Lagent 目前已经支持了包括 AutoGPT、ReAct 等在内的多个经典智能体范式,也支持了…

主流微前端框架对比与选择策略

微前端是一种架构风格,旨在将大型前端应用程序拆分为多个独立的模块,这些模块可以独立开发、测试和部署。主流的微前端框架有以下几种: Single-SPA:Single-SPA 是一个超级父级框架,可以与其他前端框架集成,…

linux环境变量设置

windows环境变量设置步骤: 右键"我的电脑"高级设置环境变量编辑"用户变量"或者"系统变量" linux下环境变量的设置步骤: 修改/etc/profile添加如下格式条目: export MAVEN_HOME/usr/local/apache-maven-3.6…

C语言指针+-整数、指针-指针、指针关系运算、指针和数组、二级指针、指针数组

文章目录 前言一、指针 - 整数二、指针 - 指针三、指针的关系运算四、指针和数组五、二级指针六、指针数组指针数组可以将几个一维数组模拟成二维数组 总结 前言 C语言指针整数、指针-指针、指针关系运算、指针和数组、二级指针、指针数组等介绍,还包括指针数组将几…

武汉大学博士,华为上班5年多,月薪多少。。。

最近,一位来自武汉大学的博士研究生透露了自己在华为公司工作五年后的薪酬情况。 据他透露,他在2018年加入华为时的月薪为2.4万,随着时间的推移,到了2023年,他的月薪已经增长至4.4万!此外,他还透…

工作后的自我介绍

您好,我叫Li,毕业于双一流**大学软件工程专业。 在大学期间通过四级,获得计算机C语言二级证书、科技立项奖(词频统计)、国家励志奖学金、优秀学生奖学金、优秀团干部、新生奖学金等。在校主修的课程有C、Java、数据结…

AI时代的GPU集群网络算力分析

浅谈GPU集群网络、集群规模和集群算力 引言在生成式AI(GenAI)和大模型时代,不仅需要关注单个GPU卡的算力,更要关注GPU集群的总有效算力。单个GPU卡的有效算力可以通过该卡的峰值算力来测算,例如,对于Nvidia…

class093 贪心经典题目专题5【左程云算法】

class093 贪心经典题目专题5【左程云算法】 前言版权推荐class093 贪心经典题目专题5最后 前言 2024-4-23 14:01:18 以下内容源自《【左程云算法】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://…