政府建设网站目标/网站推广优化外链

政府建设网站目标,网站推广优化外链,百度云服务器做php网站,做外贸网站卖什么好处目录 1. 库的概念 2. 静态库(Static Libraries) 2.1 静态库的制作 2.2 静态库的使用 2.2.1 显式指定库文件及头文件路径 2.2.2 将库文件安装到系统目录 2.2.3 将头文件安装到系统目录 3. 动态库 3.1 动态库的制作 3.2 动态库的使用 3.2.1 显式…

目录

1. 库的概念

2. 静态库(Static Libraries)

2.1 静态库的制作

2.2 静态库的使用

2.2.1 显式指定库文件及头文件路径

2.2.2 将库文件安装到系统目录

2.2.3 将头文件安装到系统目录

3. 动态库

3.1 动态库的制作

3.2 动态库的使用

3.2.1 显式指定库文件路径

2.2.2 将路径加载到环境变量中 

2.2.3 配置文件

4. 总结与补充


1. 库的概念

库(Library) 是一组预先编译好的代码(函数、类、数据等)的集合,可以被多个程序共享和重复使用。库的核心目的是代码复用,避免开发者重复编写相同的功能(如文件操作、数学计算等)。

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载如内存执行。

按照代码复用的形式,库可以分为两种:

  • 静态库:.a [Linux].lib [Windows]
  • 动态库:.so [Linux]、.dll [Windows]

库是在链接这一步被使用的,实际上就是一堆 .o 文件的集合,我们可以特定的工具来将这些 .o 文件进行打包,进而形成库。 

为举例方便,这里给出我们自己实现的简单的C语言库---myc:

// mystdio.h#pragma once
#include <stdio.h>
#define MAX 1024
#define NONE_FLUSH (1<<0)
#define LINE_FLUSH (1<<1)
#define FULL_FLUSH (1<<2)typedef struct IO_FILE
{int fileno;int flag;char outbuffer[MAX];int bufferlen;int flush_method;
}MyFile;MyFile *MyFopen(const char *path, const char *mode);
void MyFclose(MyFile *);
int MyFwrite(MyFile *, void *str, int len);
void MyFFlush(MyFile *);// mystdio.c#include "mystdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>static MyFile *BuyFile(int fd, int flag)
{MyFile *f = (MyFile*)malloc(sizeof(MyFile));if(f == NULL) return NULL;f->bufferlen = 0;f->fileno = fd;f->flag = flag;f->flush_method = LINE_FLUSH;memset(f->outbuffer, 0, sizeof(f->outbuffer));return f;
}MyFile *MyFopen(const char *path, const char *mode)
{int fd = -1;int flag = 0;if(strcmp(mode, "w") == 0){flag = O_CREAT | O_WRONLY | O_TRUNC;fd = open(path, flag, 0666);}else if(strcmp(mode, "a") == 0){flag = O_CREAT | O_WRONLY | O_APPEND;fd = open(path, flag, 0666);}else if(strcmp(mode, "r") == 0){flag = O_RDWR;fd = open(path, flag);}else{//TODO}if(fd < 0) return NULL;return BuyFile(fd, flag);
}
void MyFclose(MyFile *file)
{if(file->fileno < 0) return;MyFFlush(file);close(file->fileno);free(file);
}
int MyFwrite(MyFile *file, void *str, int len)
{// 1. 拷贝memcpy(file->outbuffer+file->bufferlen, str, len);file->bufferlen += len;// 2. 尝试判断是否满足刷新条件!if((file->flush_method & LINE_FLUSH) && file->outbuffer[file->bufferlen-1] == '\n'){MyFFlush(file);}return 0;
}
void MyFFlush(MyFile *file)
{if(file->bufferlen <= 0) return;// 把数据从用户拷贝到内核文件缓冲区中int n = write(file->fileno, file->outbuffer, file->bufferlen);(void)n;fsync(file->fileno);file->bufferlen = 0;
}// mystring.h#pragma once
int my_strlen(const char *s);// mystring.c#include "mystring.h"int my_strlen(const char *s)
{const char *start = s;while(*s){s++;}return s - start;
}

接下来,我们会介绍如何将上述的原文件打包成动静态库并使用。 

2. 静态库(Static Libraries)

  • 文件扩展名:.a(Archive)

  • 特点:
    • 在编译时,库的代码会被直接复制到最终的可执行文件中。

    • 生成的可执行文件独立,不依赖运行时环境中的库文件。

    • 缺点:文件体积较大,且更新库时需要重新编译程序。

  • 创建工具:ar(归档工具)+ ranlib(生成索引)。

  • 使用场景:适合对程序独立性要求高的场景。

2.1 静态库的制作

静态库使用 ar 指令进行打包:

ar -rc lib[库名].a [目标文件s]

lib[库名].a 是静态库文件的命名规范,实际上的库名需要去掉lib前缀以及.a扩展名。

通常来说,只有库文件是不够的,还需要将库的头文件交给用户,所以我们可以使用如下的Makefile来将库及其头文件一起打包交给用户:

SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)libmyc.a:$(OBJ)ar -rc $@ $^$(OBJ):$(SRC)gcc -c $^.PHONY:output
output:mkdir -p lib/includemkdir -p lib/mylibcp -f *.h lib/includecp -f *.a lib/mylibtar czf lib.tgz lib.PHONY:clean
clean:rm -rf *.o libmyc.a lib lib.tgz

2.2 静态库的使用

gcc/g++会默认链接c标准库,但是myc库是我们自己制作的第三方库,所以在编译时需要指定链接myc库。

假设用户已经接收到了我们的 lib.tgz 包,并且用户的代码(usercode.c)调用了我们库中的方法:

注:使用tar xzf lib.tgz进行解包得到lib目录。 

// usercode.c#include "mystdio.h"
#include "mystring.h"
#include <string.h>
#include <unistd.h>int main()
{MyFile *filep = MyFopen("./log.txt", "a");if(!filep){printf("fopen error!\n");return 1;}int cnt = 10;while(cnt--){char *msg = (char*)"hello myfile!!!";MyFwrite(filep, msg, strlen(msg));MyFFlush(filep);printf("buffer: %s\n", filep->outbuffer);sleep(1);}MyFclose(filep); // FILE *fpconst char *str = "hello bit!\n";printf("strlen: %d\n",my_strlen(str));return 0;
}
2.2.1 显式指定库文件及头文件路径

在编译时,需要指定头文件所在路径、要链接的库文件路径以及指定库文件:

gcc -o [可执行程序] [目标文件s] -I [头文件路径] -L [库路径] -l [库名]

2.2.2 将库文件安装到系统目录

我们知道,所谓安装,实际上就是把文件拷贝到指定的系统目录下。这样,在我们未显式指定库文件所在目录时,系统就能够在默认目录中找到。

当然,除了拷贝,建立链接也是可以的。 

  • /lib/usr/lib:系统级库
  • /usr/local/lib:用户安装的第三方库

我们将 libmyc.a 文件拷贝到三个库中的一个即可完成安装,此时不在需要指明库所在路径:

但是,不建议安装到系统级库,用户自己要安装的第三方库最好安装到 /usr/local/lib 中。 

2.2.3 将头文件安装到系统目录
  • /usr/include:系统级头文件
  • /usr/local/include:本地安装的第三方库头文件
  • /usr/include/<库名> 或 /usr/local/include/<库名>:特定软件的子目录

我们将自己的头文件拷贝到上述目录下即可完成安装,此时不再需要指明头文件所在路径:

3. 动态库

  • 文件扩展名:.so(Shared Object)

  • 特点:
    • 在程序运行时被动态加载到内存,多个程序可共享同一份库代码。

    • 可执行文件体积小,库更新时无需重新编译程序。

    • 缺点:依赖运行时环境中的库文件(若缺失会导致程序无法运行)。

  • 创建工具:gcc/g++ 的 -shared 选项。

  • 使用场景:大多数系统库(如 glibc)和通用功能库(如 OpenSSL)。

3.1 动态库的制作

// 编译目标文件时需要带上-fPIC选项,fPIC:产生位置无关码(position independent code) 
gcc/g++ -c -fPIC [原文件s]// 生成库文件时需要带上-shared选项,shared: 表示生成共享库格式 
gcc/g++ -o lib[库名].so [目标文件s] -shared

同样的,lib[库名].so 是命名规范,实际上的库名需要去掉lib前缀和 .so扩展名。

我们可以使用如下的Makefile来对库及其头文件进行打包:

SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)libmyc.so:$(OBJ)gcc -shared -o $@ $^$(OBJ):$(SRC)gcc -fPIC -c $^.PHONY:output
output:mkdir -p lib/includemkdir -p lib/mylibcp -f *.h lib/includecp -f *.so lib/mylibtar czf lib.tgz lib.PHONY:clean
clean:rm -rf *.o libmyc.so lib lib.tgz

3.2 动态库的使用

我们以同样的代码作为示例,将库及头文件安装到系统目录的方式与静态库一样,这里就不再重复,但是对于显式给出库文件路径的方式,我们要多说两句。

3.2.1 显式指定库文件路径

假如我们未将库文件安装到系统目录当中,并显式指定某路径下的库文件:

我们会发现编译通过了,但是:

当我们运行生成的可执行程序时,会发现系统显式找不到对应的库。

这是因为,我们仅仅告诉了编译器:“这个库是存在的”,所以编译器完成了编译。

但是动态链接是在程序运行时才将库与可执行程序产生链接,负责链接的是系统,然而系统并不知道在哪里找到这个库。 

要让操作系统在运行我们的程序时找到对应的动态库,我们可以选择安装的形式(与静态库的安装完全一致),也可采取以下几点中提到的措施。

 注意:与静态链接不同,接下来的几点措施(包括安装),都不需要重新编译可执行文件。

2.2.2 将路径加载到环境变量中 
# LD_LIBRARY_PATH:临时指定额外的库搜索路径。
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/path/to/libs

使用 ldd 命令可以查看可执行程序链接的库及其所在路径:

但是,这种方式只是临时的,重新登录或更新环境变量时就会失效。 

2.2.3 配置文件
  • /etc/ld.so.conf:系统级库路径配置文件
  • /etc/ld.so.conf.d:用户库路径配置文件目录

我们可以直接在/etc/ld.so.conf中加入我们库文件的路径,但是我们依然更建议在用户库路径配置文件目录中添加自己的配置文件:

这里sudo echo创建文件的方式居然不行,只能用编辑器创建了。

然后加载配置文件:

sudo ldconfig

 结果与2.2.2相同,这里就不展示了。

4. 总结与补充

  • gcc/g++编译命令补充:
    • [-I] :指定头文件所在目录。

    • [-L]:指定库文件所在路径。

    • [-l]:指定要链接的库。

    • [-shared]:生成动态库。

    • [-fPIC]:产生位置无关码。

    • [-static]:使用静态链接。

  • 静态库使用ar命令进行打包:
    ar -rc lib[库名].a [目标文件s]
  • 将静态库与用户目标文件一起编译即可生成可执行程序。
  •  动态库使用gcc/g++进行打包,且目标文件需要携带位置无关码:
    // 编译目标文件时需要带上-fPIC选项,fPIC:产生位置无关码(position independent code) 
    gcc/g++ -c -fPIC [原文件s]// 生成库文件时需要带上-shared选项,shared: 表示生成共享库格式 
    gcc/g++ -o lib[库名].so [目标文件s] -shared
  • 动态库在编译时需要让gcc/g++知道这个库是存在的(给出路径或安装到系统,并指定库名)。在运行时,系统需要能够找到这个库(需要安装到系统)。
  • 第三方库在编译时要指定链接这个库。
  • 在编译时,我们的系统当中可能既安装了某个库的动态版本,又安装了某个库的静态版本。此时,编译器默认能采用动态链接则采用动态链接。如果要使用静态链接则需要带上 -static 选项,一旦带上这个选项,就意味着动态链接被禁用,如果某个库只有动态链接的版本,则会发生链接失败。

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

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

相关文章

Java并发编程2(锁-Sychronized)

目录 认识Java对象头 sychronized锁原理 基本概念 工作原理 1.作用在方法上 2.作用在代码块上 工作机制 JVM优化锁 Monitor锁 wait/notify park/unpark 线程状态转换案例 死锁 概念 死锁发生的必要条件 哲学家问题 活锁 饥饿 概念 饥饿的原因 Reentrant…

现阶段高校的人工智能方案培训如何?

人工智能在未来肯定是核心发展力&#xff0c;核心竞争力&#xff0c;也是国家重点扶持的对象&#xff0c;但我还是不看好高校的人工智能方向&#xff0c;只是怕有些同学对市场前景盲目乐观&#xff0c;就轻易上车了。 你要是985以上的高校&#xff0c;可以考虑选择人工智能&…

JavaScript中的继承有哪些方式?各有什么优缺点

在 JavaScript 中&#xff0c;继承主要通过原型链实现&#xff0c;常见的继承方式有以下几种&#xff0c;每种方式都有其优缺点&#xff1a; 1. 原型链继承 1. 实现方式&#xff1a;将子类的原型对象指向父类的实例。 function Parent() {} function Child() {} Child.protot…

深入理解指针(3)(C语言版)

文章目录 前言 一、字符指针变量二、数组指针变量2.1 数组指针变量是什么2.2 数组指针变量怎么初始化2.2.1 静态初始化2.2.2 动态初始化 三、二维数组传参的本质四、函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 typedef关键字4.4拓展 五、函数指针数组六、转…

csp信奥赛C++常用的数学函数详解

csp信奥赛C常用的数学函数详解 在信息学奥林匹克竞赛&#xff08;信奥赛&#xff09;中&#xff0c;C 的 <cmath> 头文件提供了丰富的数学函数&#xff0c;用于高效处理数学运算。以下是常用系统数学函数的详细讲解及汇总表格。 绝对值函数 int abs(int x)&#xff1a;返…

ChatDBA VS DeepSeek:快速诊断 OceanBase 集群新租户数据同步异常

社区王牌专栏《一问一实验&#xff1a;AI 版》改版以来已发布多期&#xff08;51-60&#xff09;&#xff0c;展现了 ChatDBA 在多种场景下解决问题的效果。 下面让我们正式进入《一问一实验&#xff1a;AI 版》第 62 期&#xff0c;看看 ChatDBA 最新效果以及与热门大模型 De…

oracle数据库(数据库启动关闭/sqlplus登录及基本操作/设置字符集/distinct去重)

目录 1. Oracle数据库启动 2. Oracle数据库关闭 3. sqlplus登录Oracle数据库 3.1 使用sqlplus登录Oracle数据库 3.2 使用sqlplus登录Oracle数据库 3.3 远程登录 3.4 解锁用户 3.5 修改用户密码 3.6 查看当前语言环境 4. sqlplus基本操作 4.1 显示当前用户 4.2 查看当前用户…

Java 大视界 -- Java 大数据在智能金融区块链跨境支付与结算中的应用(154)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

在Cesium中使用ThreeJs材质(不是场景融合哦)

在Cesium中使用ThreeJs材质(不是场景融合哦&#xff09;_哔哩哔哩_bilibili

给Web开发者的HarmonyOS指南02-布局样式

给Web开发者的HarmonyOS指南02-布局样式 本系列教程适合鸿蒙 HarmonyOS 初学者&#xff0c;为那些熟悉用 HTML 与 CSS 语法的 Web 前端开发者准备的。 本系列教程会将 HTML/CSS 代码片段替换为等价的 HarmonyOS/ArkUI 代码。 布局基础对比 在Web开发中&#xff0c;我们使用CS…

京东软件测试岗位经典面试题(附答案)

1、黑盒测试的测试用例常见设计方法都有哪些&#xff1f;请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。 1&#xff09;等价类划分&#xff1a;等价类是指某个输入域的子集合.在该子集合中&#xff0c;各个输入数据对于揭露程序中的错误都是等效的.并合理地假…

3.26[a]paracompute homework

5555 负载不平衡指多个线程的计算量差异显著&#xff0c;导致部分线程空转或等待&#xff0c;降低并行效率。其核心矛盾在于任务划分的静态性与计算动态性不匹配&#xff0c;尤其在处理不规则数据或动态任务时尤为突出。以稀疏矩阵的向量乘法为例&#xff0c;假设其非零元素分…

帕金森患者的生活重塑:从 “嘴” 开启康复之旅

当提到帕金森病&#xff0c;许多人会联想到震颤、僵硬和行动迟缓等症状。这种神经系统退行性疾病&#xff0c;给患者的生活带来了巨大的挑战。然而&#xff0c;你可知道&#xff0c;帕金森患者恢复正常生活&#xff0c;可以从 “嘴” 开始管理&#xff1f; 帕金森病在全球影响着…

Android14 Settings应用添加有线网开关条目实现

Android14 Settings应用添加有线网开关条目 文章目录 Android14 Settings应用添加有线网开关条目一、前言二、适配修改1、network_provider_settings.xml2、NetworkProviderSettings.java3、TurnOnOffEthernetNetworkController.java4、去除有线网提示条目。5、效果UI&#xff…

Axure RP设计软件中的各种函数:包括数字、数学、字符串、时间及中继器函数,详细解释了各函数的用途、参数及其应用场景。

文章目录 引言函数分类数字函数数学函数字符串函数时间函数函数中继器函数引言 在axure交互设计时,函数可以用在条件公式和需要赋值的地方,其基本语法是用双方括号包含,变量值和函数用英文句号连接。 在交互事件编辑器中通过fx按钮插入函数表达式,例如设置文本内容为: …

c#难点整理3

1.静态类的说明 a.静态类里不能定义实例方法&#xff0c;实例属性&#xff0c;所以说非静态类是无法继承静态类的。父类无法拥有实例化的方法和属性&#xff0c;子类可以&#xff0c;这从逻辑上是矛盾的&#xff0c;不符合继承的逻辑。 b.那么静态类与静态类之间能否继承能呢…

Win11+VS2022+CGAL5.6配置

1. CGAL库简介 CGAL&#xff08;Computational Geometry Algorithms Library&#xff09;是一个开源的计算几何算法库&#xff0c;主要用于处理几何问题和相关算法的实现。它提供了丰富的几何数据结构和高效算法&#xff0c;覆盖点、线、多边形、曲面等基本几何对象的表示与操…

手搓全自动文章多平台发布系统:5、跨页面接入playwright类,修改ui_components.py,整合到main.py

昨天已经要多上下文,单上下文的模块中测试成功了,今天要想法接入。 整理完成的所有代码如下: 结构如图: main.py import sys from PyQt6 import QtWidgets from modules.ui_components import TableManager # 导入界面类 import asyncio# 在主函数中使用 qasync 整合事…

涨薪技术|使用Dockerfile创建镜像

上次的推文内容中介绍了如何使用docker commit的方法来构建镜像&#xff0c;相反推荐使用被称为Dockerfile的定义文件和docker build命令来构建镜像。Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像&#xff0c;之后使用docker build命令基于该Dockerfile中的指令…

成都国际数字影像产业园:打造数字影像产业新高地

成都国际数字影像产业园&#xff1a;打造数字影像产业新高地 成都国际数字影像产业园正致力于构筑数字影像产业的新高地&#xff0c;成为推动区域数字经济发展的重要引擎。 核心定位与目标 该园区精准定位于数字影像文创产业&#xff0c;旨在打造集内容创作、技术研发、人才…