【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.mfbz.cn/a/558954.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有没有手机上使用的库存软件

库存软件是一种仓库的信息管理系统,它主要针对出库与入库这些数据进行管理,传统的库存管理都是在电脑上安装一个专门的数据库管理系统进行管理,这也是一种比较成熟的管理方式,那么有没有手机上使用的库存软件。 手机上使用的库存软…

开发工具——postman使用教程详解

一、概念 1、Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件,Postman分为Postman native app和Postman Chrome app两个版本。目前Chrome app已停止维护,官方不推荐使用该版本。 2、官网下载地址:http://www.getpostman.com…

离线数仓数据导出-hive数据同步到mysql

离线数仓数据导出-hive数据同步到mysql MySQL建库建表数据导出 为方便报表应用使用数据,需将ads各指标的统计结果导出到MySQL数据库中。 datax支持hive同步MySQL:仅仅支持hive存储的hdfs文件导出。所以reader选hdfs-reader,writer选mysql-wri…

架构师系列-搜索引擎ElasticSearch(十)- 索引别名及重建

索引别名 别名,有点类似数据库的视图,别名一般都会和一些过滤条件相结合,可以做到即使是同一个索引上,让不同人看到不同的数据。 别名的作用 在开发中,一般随着业务需求的迭代,较老的业务逻辑就要面临更新…

架构设计-权限系统之通用的权限系统设计方案

一个系统,如果没有安全控制,是十分危险的,一般安全控制包括身份认证和权限管理。用户访问时,首先需要查看此用户是否是合法用户,然后检查此用户可以对那些资源进行何种操作,最终做到安全访问。身份认证的方…

Junit 基础-ApiHug准备-测试篇-009

🤗 ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱,有温度,有质量,有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace 注解 J…

STM32直接存储器存取DMA

前提知识: 1、STM32F103内部存储器结构以及映射 STM32F103的程序存储器、数据存储器、寄存器和IO端口被组织在同一个4GB的线性地址空间内。数据字节以小端模式存放在存储器中。即低地址中存放的是字数据的低字节,高地址中存放的是字数据的高字节 可访问…

React间接实现一个动态组件逻辑

在开发一个浏览器插件的时候,用的plasmo框架和react支持的,里面使用react开发一个菜单功能,但是又不想使用react-router,所以就想着能不能使用一个很简单的方式做一个替代方案?那肯定是可以。 我在引入一个组件后&…

C语言 | Leetcode C语言题解之第40题组合总和II

题目: 题解: int** ans; int* ansColumnSizes; int ansSize;int* sequence; int sequenceSize;int** freq; int freqSize;void dfs(int pos, int rest) {if (rest 0) {int* tmp malloc(sizeof(int) * sequenceSize);memcpy(tmp, sequence, sizeof(int…

Golang | Leetcode Golang题解之第37题解数独

题目: 题解: func solveSudoku(board [][]byte) {var line, column [9][9]boolvar block [3][3][9]boolvar spaces [][2]intfor i, row : range board {for j, b : range row {if b . {spaces append(spaces, [2]int{i, j})} else {digit : b - 1line…

如何实现外网访问内网ip?公网端口映射或内网映射来解决

本地搭建服务器应用,在局域网内可以访问,但在外网不能访问。如何实现外网访问内网ip?主要有两种方案:路由器端口映射和快解析内网映射。根据自己本地网络环境,结合是否有公网IP,是否有路由权限,…

Vast+产品展厅 | Vastbase G100数据库是什么架构?(1)

Vastbase G100是海量数据融合了多年对各行业应用场景的深入理解,基于openGauss内核开发的企业级关系型数据库。 了解Vastbase G100的架构,可以帮助您确保数据库系统的高效、可靠和安全运行。 “Vast产品展厅”将分两期,为您详细讲解Vastbas…

Excel模板导入、导出工具类

1.引入maven依赖&#xff0c;利用hutool的excel读取 Hutool-poi对excel读取、写入 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency> <depen…

手写Java设计模式之工厂模式,附源码解读

工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一&#xff0c;这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 工厂模式提供了一种创建对象的方式&#xff0c;而无需指定要创建的具体类。 工厂模式属于创建型…

智慧园区引领产业智能化升级:科技创新驱动打造智慧化、高效化产业新未来

随着全球科技革命的深入推进&#xff0c;以大数据、云计算、物联网、人工智能等为代表的新一代信息技术正深刻改变着传统产业的发展模式。在这一背景下&#xff0c;智慧园区作为产业智能化升级的重要载体和平台&#xff0c;正以其前瞻性的规划、创新的科技和卓越的实践&#xf…

桥接模式【结构型模式C++】

1.概述 桥接模式是一种结构型设计模式&#xff0c;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;它通过提供抽象化和实现化之间的桥接结构&#xff0c;来实现二者的解耦。 这种模式涉及到一个作为桥接的接口&am…

完整、免费的把pdf转word文档

在线工具网 https://www.orcc.online/pdf 支持pdf转word&#xff0c;免费、完整、快捷 登录网站 https://orcc.online/pdf 选择需要转换的pdf文件&#xff1a; 等待转换完成 点击蓝色文件即可下载 无限制&#xff0c;完整转换。

C语言-浮点数在内存中的存储

目录 C语言-浮点数在内存中的存储 练习 浮点数的存储 浮点数存的过程 浮点数在内存的存储 浮点数取的过程 C语言-浮点数在内存中的存储 常见的浮点数&#xff1a;3.14149、1E10&#xff08;科学计数法表示形式&#xff1a;1.0*10^10&#xff09;等&#xff0c;浮点数家族…

数据赋能(62)——要求:数据管理部门能力

“要求&#xff1a;数据管理部门能力”是作为标准的参考内容编写的。 在实施数据赋能中&#xff0c;数据管理部门的能力体现在多个方面&#xff0c;关键能力如下图所示。 在实施数据赋能的过程中&#xff0c;数据管理部门应具备的关键能力如下。 数据治理与标准化能力 数据管…