网站后台登录怎么做的河北邯郸建网站
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:55
当前位置: 首页 > news >正文
网站后台登录怎么做的,河北邯郸建网站,网站建设ssc源码最新,公司网站建设内部调查文章目录 一、引言二、C/C源文件的编译过程三、静态库1、静态库的定义和原理2、静态库的优缺点3、静态库的创建和使用a、创建静态库b、使用静态库 四、动态库1、动态库的定义和原理2、动态库的优缺点3、动态库的创建和使用示例a、创建动态库b、使用动态库 五、动静态库的比较 一… 文章目录 一、引言二、C/C源文件的编译过程三、静态库1、静态库的定义和原理2、静态库的优缺点3、静态库的创建和使用a、创建静态库b、使用静态库 四、动态库1、动态库的定义和原理2、动态库的优缺点3、动态库的创建和使用示例a、创建动态库b、使用动态库 五、动静态库的比较 一、引言 在Linux系统开发中库文件扮演着至关重要的角色。它们提供了程序运行所需的各种功能使得开发者能够高效地复用代码减少重复劳动。库文件通常分为动态库也称为共享库和静态库两种类型它们在程序链接和运行阶段扮演着不同的角色。 二、C/C源文件的编译过程 当我们使用gcc来编译一个C源文件会经历如下过程 从图中我们可以看出GCC处理HelloWorld.c的大致过程预处理—编译—汇编—链接。 下面我们详细解释该过程 预处理Preprocessing 预处理阶段会做一些文本操作。注释的删除、#include头文件的包含、#define符号的替换等。#define与#include称为预处理指令。所有的预处理的指令都是此过程进行。 在这个阶段编译器会处理源代码文件HelloWorld.c中的预处理指令如#include、#define等。 #include stdio.h这样的指令会告诉编译器将标准输入输出头文件stdio.h的内容包含到源文件中。 我们通常使用-E选项来只执行预处理阶段并将输出重定向到一个文件。例如 gcc -E HelloWorld.c -o HelloWorld.i预处理后的输出文件通常是.i扩展名如HelloWorld.i。 编译Compilation 编译阶段将预处理后的文件转换成汇编代码。且对预处理后的文件进行语法分析、词法分析、语义分析、符号汇总并生成汇编代码。 我们通常使用-S选项来只执行编译阶段生成汇编代码。例如 gcc -S HelloWorld.i -o HelloWorld.s如果直接从.c文件编译到.s文件命令如下 gcc -S HelloWorld.c -o HelloWorld.s汇编代码通常以.s为扩展名。如HelloWorld.s该文件包含了汇编代码。 汇编Assembly 汇编阶段将汇编语言文件转换成机器语言的目标文件。把汇编代码翻译成二进制指令生成的是目标文件目标文件中存放的都是二进制的指令。即形成符号表。 我们通常使用-c选项来执行汇编阶段生成目标文件object file。 gcc -c HelloWorld.s -o HelloWorld.o注意同样地通常会直接从.c或.s文件汇编到.o文件。从.s文件汇编的命令如上所示。 如果直接从.c文件汇编到.o文件命令如下 gcc -c HelloWorld.c -o HelloWorld.o目标文件通常以.o为扩展名。如HelloWorld.o。 链接Linking 链接阶段是将目标文件.o文件与所需的库文件合并起来生成最终的可执行文件。这个过程会进行合并段表、符号表的合并和重定位等。链接器会解析目标文件中的外部符号引用如函数调用并将它们与库文件中的定义连接起来。最终生成的可执行文件。 使用gcc命令不带-c、-S、-E等选项来执行链接阶段生成可执行文件。如果程序使用了任何标准库函数如printf则链接器会自动链接必要的库。例如 gcc HelloWorld.o -o HelloWorld或者如果直接从.c文件开始并且没有中间步骤可以简单地使用 gcc HelloWorld.c -o HelloWorld这将生成一个名为HelloWorld的可执行文件该文件包含了完整的机器码指令可以直接运行在计算机上。 三、静态库 1、静态库的定义和原理 静态库 (Static Library) 是一种在编译时链接到程序中的库文件它的格式为.a在Linux系统中。静态库包含了程序运行所需的所有代码和数据当程序编译时链接器会将静态库中的代码和数据直接复制到生成的可执行文件中。 我们观察使用了静态库的程序 使用 ldd a.out 命令检查 a.out 的动态链接依赖时输出了 not a dynamic executable这是因为 a.out 是一个静态链接的可执行文件它不依赖于任何外部的动态链接库。使用 file a.out 命令查看文件类型时输出描述了这是一个静态链接的 ELF 64 位可执行文件并且没有动态链接器如 /lib64/ld-linux-x86-64.so.2的引用。 因此使用静态库生成可执行程序后该程序运行时就不依赖外部库文件可独立运行但生成的可执行文件体积较大。 gcc -o test_static test.c -static 这个命令使用了 -static 选项将 test.c 编译并链接为一个名为 test_static 的可执行文件。-static 选项告诉链接器在创建可执行文件时应该使用静态库而不是动态库。这意味着它在运行时不需要动态链接器来解析任何动态库依赖。 gcc -o test_shared test.c 这个命令将 test.c 编译并链接为一个名为 test_shared 的可执行文件且没有使用任何特殊的链接选项。默认情况下链接器会使用动态库来解析程序中的依赖。这意味着 test_shared 在运行时需要加载它依赖的共享库。这种方法生成的可执行文件通常较小因为它不包含它所依赖的库的完整副本但它需要这些库在运行时可用。 因此我们可以明显观察到两者的大小差距。 2、静态库的优缺点 优点: 执行速度快: 由于代码已经包含在可执行文件中不需要运行时动态链接可以减少启动时间。即编译成功的可执行文件可以独立执行而不需要再向外部要求读取函数库的内容 。确定性: 程序的行为不会受到其他程序使用相同库的不同版本的影响。 缺点: 占用空间: 每个使用静态库的可执行文件都会包含库的一份副本导致文件体积增大。更新困难: 当静态库更新时所有使用该库的程序都需要重新编译和链接。资源浪费: 如果多个程序使用相同的静态库那么每个程序中都会有一份库的副本浪费内存和磁盘空间。 3、静态库的创建和使用 a、创建静态库 下面我们根据上图来介绍我们的静态库创建过程我们有两个C源文件mymath.c 和 mystdio.c以及他们对于的.h文件。 编译源文件为目标文件 使用gcc编译器将源文件编译为目标文件。目标文件是包含机器代码但尚未链接的文件。 gcc -c mymath.c gcc -c mystdio.c 这将生成mystdio.o和mymath.o两个目标文件。 创建静态库 使用ar工具将目标文件打包成静态库。在Linux系统中静态库通常以.a为扩展名。 ar -rc libmylib.a mymath.o mystdio.o这将创建一个名为libmylib.a的静态库。使用 ar 命令来创建一个静态库文件 libmylib.a这个库文件包含了 mymath.o 和 mystdio.o 这两个目标文件。我们分析该命令 ar这是GNU归档器命令用于创建、修改和提取静态库文件通常是 .a 文件。-r替换现有的目标文件或添加新的目标文件到归档文件中。replace-c创建一个归档文件如果它不存在的话。这个选项与 -r 一起使用时意味着如果归档文件已经存在则替换其中的同名目标文件如果归档文件不存在则创建一个新的归档文件。create b、使用静态库 编写主程序 编写一个主程序例如myprogram.c它调用静态库中的函数。在程序中我们需要包含定义库函数的头文件并在链接时指定库文件。 编译和链接主程序 使用gcc编译器编译主程序并在链接时指定静态库以便使用 mymath.o 和 mystdio.o 中定义的函数或变量。在链接时我们需要告诉编译器和链接器静态库文件的路径和名称通常使用 -L 和 -l 选项。例如 gcc -o myprogram myprogram.c -L /path/to/lib_test -lmylib -I /path/to/lib_include这里-L告诉编译器在哪个目录下搜索库文件这里的 /path/to/lib_test 应该替换为实际存放 libmyc.a 的路径。注意 -l 选项后面跟的是库名不包括前缀 lib 和后缀 .a。-L选项后跟的是存放库的路径。-I告诉编译器在哪个目录下搜索头文件这里的 /path/to/lib_include 应该替换为实际存放所使用头文件的路径。 下面我们进行实验我们编写如下用于构建并组织构建静态库libmylib.a的makfile #形成静态库 libmylib.a:mymath.o mystdio.oar -rc \( \)^%.o:%.cgcc -c \( .PHONY:clean clean:rm -rf *.o mylib *.a.PHONY:output output:mkdir -p mylib/includemkdir -p mylib/libcp ./*.h mylib/includecp ./*.a mylib/lib这个makefile定义了两个目标静态库和对象文件的构建规则以及两个伪目标clean和output用于清理文件和组织构建的输出。 此时我们已经构建好当前的静态库现在该目录下就只有test.c和我们刚才打包好的静态库。 首先我们使用gcc来编译我的C源文件 图中错误表示编译器在编译 test.c 文件时它找不到名为 mymath.h 的头文件。 gcc 在编译 test.c 时找不到 mymath.h 头文件。因此我们需要在编译时告诉 gcc 在哪里可以找到这些头文件。我们使用-I选项告诉编译器在哪个目录下搜索头文件 图中错误表示当编译器编译 test.c 时它看到了对 myAdd 函数的调用很可能是在 main 函数中但是在链接阶段链接器找不到这个函数在何处定义。 -l 和 -L 选项来告诉链接器链接到 libmylib.a 静态库。-l 选项后面跟着库名不带前缀 lib 和后缀 .a而 -L 选项后面跟着库文件的搜索路径。 注意 在Linux系统上动态库通常以.so为扩展名静态库通常以.a为扩展名。这些库文件在命名时通常会遵循一个特定的模式即前缀lib然后是库名再是可选的版本信息最后是文件扩展名.so或.a。 例如 libyaml-0.so.2 是一个为软链接它指向实际的库文件 libyaml-0.so.2.0.6。libyaml-0.so.2.0.6 是实际的库文件。 当我们谈论“库名”时我们通常指的是去掉前缀lib、扩展名.so、.a或 .so.版本号以及任何版本信息之后的部分。因此在这个例子中 符号链接名或称为“库引用名”libyaml-0.so.2实际库文件名libyaml-0.so.2.0.6库名不包括版本libyaml 注意库名 libyaml 是从文件名 libyaml-0.so.2 或 libyaml-0.so.2.0.6 中去掉 lib 前缀、.so 或 .so.版本号 后缀后得到的。这是因为在编写代码并链接到库时通常会使用不包括这些前缀和后缀的库名。例如在 C 或 C 中会使用 -lyaml 来链接到 libyaml 库。 在链接程序时我们通常只需要指定库名不包括前缀lib和后缀链接器会自动在系统的库路径如/lib、/usr/lib等中查找相应的库文件。 四、动态库 1、动态库的定义和原理 动态库 (Dynamic Library) 是一种在程序运行时可以动态加载的库。它的格式为.so (Shared Object) 在 Linux 系统中动态库也称为共享库。 动态库是一种在程序运行时可以动态加载的库。这意味着动态库的内容包括函数、变量和类等并不在编译时被包含进程序本身而是在程序运行时才根据需要被加载。因此多个程序可以共享同一个动态库从而节省内存空间。 我们来观察使用了动态库的程序 使用 ldd 命令检查了 a.out 的动态链接依赖输出显示它依赖于 libc.so.6C标准库和 ld-linux-x86-64.so.2动态链接器。使用 file 命令查看了 a.out 的文件类型信息输出详细描述了它是一个64位的位置无关可执行文件PIE动态链接的并且为 GNU/Linux 3.2.0 或更高版本设计。同时输出还包含了构建IDBuildID和其他一些信息。 从这些信息中我们可以确认。a.out 是一个动态链接的可执行文件这意味着它在运行时需要依赖其他动态库如 libc.so.6。 那么动态库的原理是什么呢 实时加载当程序需要调用动态库中的函数或变量时操作系统会实时加载动态库到内存中。这样只有当程序实际需要某个库时才会占用相应的内存资源。共享性由于动态库是在程序运行时被加载的因此多个程序可以共享同一个动态库。这意味着如果多个程序都使用了同一个动态库那么这些程序在运行时只需要加载一份动态库到内存中从而节省了内存空间。动态链接在程序运行时操作系统会将程序与动态库进行动态链接。这种链接方式允许程序在运行时根据需要加载或卸载动态库从而提高了程序的灵活性和可维护性。 动态库是程序在运行的时候才去链接相应的动态库代码的多个程序共享使用库的代码。一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表而不是外部函数所在目标文件的整个机器码。 在可执行文件开始运行前外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中这个过程称为动态链接。动态库在多个程序间共享节省了内存空间操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用节省了内存。 下面我们来理解动态库的使用过程 使用了动态库的C/C源文件需要通过编译链接才能被使用。那么我们通常使用gcc来编译链接得到可执行程序然后操作系统来运行它的可执行程序。 编译时的搜索路径——gcc需要 在编译程序时如果程序引用了动态库中的函数或数据编译器如gcc需要知道这些函数或数据在哪些动态库中存在。这通常通过包含头文件.h文件来实现这些头文件声明了库中的函数和数据并可能还包含了指定库文件名的预处理器指令。 然而仅仅知道函数和数据的声明是不够的编译器还需要知道这些函数和数据在动态库中的实际定义。这通常通过编译器选项来指定我们将在后文详细描述该过程的实现方法。 因此在编译时编译器如GCC需要知道在哪里可以找到所需的动态库的头文件.h 文件以及用于链接的库文件。 运行时的库搜索路径——操作系统需要 当程序运行时操作系统需要找到程序所依赖的动态库文件并将它们加载到内存中以便程序能够调用库中的函数。操作系统会按照一定的搜索顺序来查找这些库文件。 如果操作系统在所有这些路径中都没有找到所需的动态库文件程序就会因为找不到依赖的库而无法正常运行。 编译是编译器的事情运行是os的事情 这句话的意思是编译程序是编译器的责任编译器需要确保程序在语法和语义上是正确的并且所有引用的函数和数据都有定义。而运行程序则是操作系统的责任操作系统需要确保程序所需的所有资源包括动态库文件都是可用的并且程序能够正确地执行。 编译器和操作系统在程序的生命周期中扮演着不同的角色但它们之间需要密切合作以确保程序能够正确地编译和运行。 编译与运行的区别 编译是源代码到可执行文件或库的转换过程由编译器完成。编译器处理源代码检查语法和语义生成机器代码或中间代码并可能链接库以创建最终的可执行文件或库。运行是执行编译后的代码的过程由操作系统管理。操作系统加载程序到内存中解析程序中的动态链接执行程序并处理程序运行时的各种请求和事件。 因此编译时关注的是源代码和库的静态关系而运行时关注的是程序与操作系统的动态交互。动态库在这两个过程中都扮演着重要角色但需要在不同的阶段以不同的方式进行处理。 综上所述我们可以得出下面的结论运行时不需要头文件只需要动态库。编译需要头文件和库。 在编译一个程序时编译器需要头文件来解析函数、类和其他实体的声明以确保源代码中使用的所有标识符都是已定义和可用的。此外如果程序依赖于某个库中的函数或类那么编译器还需要这个库的头文件以便知道如何正确地链接到这些库中的函数或类。 但是一旦程序被编译并链接成可执行文件它就不再需要头文件了。在运行时操作系统加载并执行这个可执行文件它只需要与可执行文件相关联的动态库如果有的话。这些动态库包含了程序在运行时需要调用的函数和类的实现。 所以简而言之 编译时需要头文件和库静态库或动态库的头文件。运行时只需要动态库如果程序依赖于它们。 注意静态库在编译时会被链接到可执行文件中因此运行时不需要额外的静态库文件。而动态库在运行时由操作系统加载到内存中并与可执行文件一起使用。 下面我们再从进程地址空间的角度来理解 首先我们理解一下动态库的本质在多个系统进程中共享公共的代码和数据只需要存一份。 当程序使用动态库时操作系统会在内存中为动态库分配一块共享区域即上图中的共享区并将该区域映射到所有使用该动态库的进程的地址空间中。这样当多个进程同时访问动态库中的函数或数据时它们实际上是在访问同一块内存区域。这种共享机制使得动态库成为了一种非常高效的代码和数据复用方式。 动态库通常存放在系统的特定目录下如 /usr/lib、/usr/local/lib 或 /lib。这些目录会被动态链接器如 ld-linux.so和操作系统搜索以找到需要的库文件。 动态库加载过程 加载到进程地址空间当程序尝试调用动态库中的函数时动态链接器会将该库加载到进程的地址空间中即上图的“共享区”。符号解析动态链接器会解析程序引用的动态库中的符号如函数和数据。它会在动态库的符号表中查找这些符号的地址并在程序的地址空间中建立相应的映射。调用库函数当程序调用动态库中的函数时它会跳转到地址空间中的共享区执行库中的函数代码。执行完成后程序会跳转回原来的位置继续执行。页表映射为了使得程序能够正确地访问这个共享区中的代码和数据操作系统会在页表中建立相应的条目将动态库的虚拟地址映射到这块共享区的物理地址。并在每个需要使用该动态库的进程的页表中建立相应的映射条目。这样当程序访问动态库中的函数或数据时处理器就可以通过页表找到对应的物理地址从而实现对动态库的访问。 因此不论多少程序使用内存中只会存在该动态库指令的一份拷贝实现了代码共享在程序运行时才会去引用库中的相关函数并不把这些函数的指令包含进去。 理解动态库动态链接和加载 动态链接在程序运行时动态链接器将程序所需的动态库链接到程序的虚拟地址空间中。这样程序就可以在运行时动态地加载和使用动态库中的函数和数据。动态加载动态加载允许程序在运行时根据需要加载动态库。这意味着程序可以在启动时只加载必要的代码和数据然后在需要时动态地加载其他代码和数据。这有助于提高程序的启动速度和灵活性。动态链接和加载的优点包括节省内存因为多个程序可以共享同一个动态库、支持多语种因为动态库可以与不同的编程语言一起使用、可重复利用因为动态库可以被多个程序共享以及便于大项目的开发因为可以将功能拆分成多个独立的动态库。 虚拟地址空间不仅是操作系统要遵守的编译器在编译程序时也需要遵守。 进程地址空间是多任务操作系统中每个进程所拥有的独立的、隔离的内存环境。在操作系统中每个进程都运行在属于自己的地址空间。操作系统通过虚拟地址空间来管理物理内存和磁盘空间实现内存的保护和隔离确保每个进程都有独立的内存空间并且只能访问自己的内存空间不能访问其他进程的内存空间。 编译器在编译程序时也需要遵守虚拟地址空间的规则。编译器将源代码转换为机器代码时会生成程序所需要的虚拟地址空间布局。编译器需要确保程序在运行时能够正确地访问和操作虚拟地址空间中的数据和代码。编译器还需要考虑虚拟地址空间和物理地址空间之间的映射关系以及如何处理内存不足等问题。 因此虚拟地址空间是操作系统和编译器都需要遵守的重要概念。操作系统通过虚拟地址空间来管理内存和隔离进程而编译器则通过虚拟地址空间来生成可执行的程序代码并确保程序能够正确地访问和操作虚拟地址空间中的数据和代码。 2、动态库的优缺点 优点 代码重用动态库允许多个程序共享使用相同的代码和数据从而减少了内存的使用并提高了代码的重用性。资源节约由于多个程序可以共享使用同一个动态库因此不需要在每个程序中都包含相同的代码和数据从而节省了磁盘空间。更新和维护方便当动态库更新时所有使用该库的程序都可以立即受益而无需重新编译或重新分发程序本身。这大大简化了软件的更新和维护过程。 缺点 加载时间由于动态库在程序运行时需要被加载到内存中因此相对于静态链接的程序来说动态链接的程序在启动时可能会有一定的延迟。依赖问题动态链接的程序依赖于外部的动态库文件。如果这些库文件不存在、版本不匹配或路径不正确程序将无法正常运行。这增加了程序部署和管理的复杂性。 3、动态库的创建和使用示例 a、创建动态库 上图中执行一系列步骤来创建一个动态库文件。该文件可以在多个程序之间共享而不需要在每个程序中都包含相同的代码。 编译 .c 为 .o gcc -c -fPIC mystdio.c gcc -c -fPIC mymath.c这两条命令使用 gcc来编译 *.c 源文件。-c 选项告诉 gcc 只编译源文件但不进行链接。-fPIC 选项告诉编译器生成位置无关代码Position Independent Code这是创建共享库所必需的。编译后的输出是一个名为 *.o 的目标文件。 链接 mystdio.o 和 mymath.o 为 libmyc.so gcc -shared -o libmyc.so mystdio.o mymath.o这条命令使用 gcc 的 -shared 选项来创建一个共享库。-o libmyc.so 指定了输出文件的名称即 libmyc.so。然后命令列出了要链接的所有目标文件mystdio.o 和 mymath.o。链接器将这些目标文件组合成一个共享库该库可以在运行时由多个程序共享。 我们编写如下用于构建并组织构建静态库libmyc.so的makfile libmyc.so:mymath.o mystdio.ogcc -shared -o \) \(^ %.o:%.cgcc -c -fPIC \)
mymath.o:mymath.c
gcc -c -fPIC $ # mystdio.o:mystdio.c
gcc -c -fPIC $ .PHONY:clean
clean:rm *.o libmyc.sob、使用动态库
现在可以在其他C或C程序中链接这个静态库以便使用 mymath.o 和 mystdio.o 中定义的函数或变量。在链接时需要告诉编译器和链接器静态库文件的路径和名称通常使用 -L 和 -l 选项对于gcc和g。
编译时链接
在编译程序时需要在编译命令中指定包含头文件的目录如果有的话和库文件的搜索路径。使用 -I 选项指定头文件搜索路径使用 -L 选项指定库文件搜索路径使用 -l 选项指定库名不包含前缀 lib 和后缀 .so。
gcc -o myprogram myprogram.c -I /path/to/headers -L /path/to/lib_test -lmyc这里的 /path/to/lib_test 应该替换为实际存放 libmyc.so 的路径。/path/to/headers应该替换为实际存放 *.h 的路径。
运行时查找库
当程序运行时操作系统需要知道在哪里可以找到 libmyc.so。这通常通过以下几种方式之一实现
2.1 LD_LIBRARY_PATH 环境变量
可以将包含 libmyc.so 的目录添加到 LD_LIBRARY_PATH 环境变量中。例如
export LD_LIBRARY_PATH/path/to/lib_test:$LD_LIBRARY_PATH
./myprogram这种方法只影响当前终端会话。
2.2 将库安装到标准位置
如果希望多个程序都能使用这个库可以将 libmyc.so 复制到标准库目录如 /usr/lib 或 /usr/local/lib。这样程序在系统启动时就可以自动找到库了。
sudo cp libmyc.so /usr/local/lib/
./myprogram注意在复制库文件到系统目录之前请确保拥有相应的权限并且了解这可能对其他系统用户产生影响。
示例
假设您已经将 libmyc.so 放在了 /path/to/lib_test 目录中并且您有一个 myprogram.c 文件可以这样编译和运行它
编译 myprogram.c 并链接到 libmyc.so
gcc -o myprogram myprogram.c -L/path/to/lib_test -lmyc # 设置 LD_LIBRARY_PATH 环境变量仅在当前终端会话中有效
export LD_LIBRARY_PATH/path/to/lib_test:\(LD_LIBRARY_PATH export LD_LIBRARY_PATH/home/zyb/study_code/file_sys/lib_test/user
/mylib/lib:\)LD_LIBRARY_PATH # 运行程序
./myprogram或者如果已经将库安装到了标准位置并更新了缓存那么可以直接运行程序而无需设置 LD_LIBRARY_PATH。
下面我们进行实验我们编写如下用于构建并组织构建静态库libmyc.a的makfile
#形成动态库
libmyc.so:mymath.o mystdio.ogcc -shared -o \( \)^
%.o:%.cgcc -c -fPIC $
.PHONY:clean
clean:rm -rf *.o libmyc.so mylib .PHONY:output
output:mkdir -p mylib/includemkdir -p mylib/libcp -rf *.h mylib/includecp -rf *.so mylib/lib该makefile与上文构建静态库类似不再赘述。
下面我们来观察动态库动态搜索和链接过程 编译未链接库 首先尝试编译main.c但没有链接到libmyc.so库。因此链接器报告了在main.c中引用了未定义的函数myAdd和my_fopen。 解决方案在编译时添加-L选项指定库文件的位置并使用-l选项指定库名注意库名不需要前缀lib和后缀.so。 链接时未找到库 在第二次尝试中添加了-lmyc但忘记添加-L ./mylib/lib/来指定库文件的搜索路径。因此链接器无法找到libmyc.so。 解决方案在编译命令中同时添加-L和-l选项。 运行时找不到库 当尝试运行myexe时系统报告找不到libmyc.so库。这是因为运行时链接器动态链接器没有在默认的库搜索路径中找到该库。 解决方案 1、直接把动态库复制到默认的库搜索路径中。 2、添加到环境变量 LD_LIBRARY_PATH中。 这个环境变量指定了动态链接器如 ld-linux.so在标准位置如 /lib 和 /usr/lib之外搜索动态库如 .so 文件在 Linux 上的目录列表。当运行一个程序并且该程序依赖于某个动态库时动态链接器会首先查看 LD_LIBRARY_PATH 中列出的目录来查找这个库。如果找到了则使用这个库如果没有找到则继续搜索标准位置。 3、建立软链接 假设动态库位于 /path/to/your/library/libmyserver.so并且您想将它链接到系统的标准库目录例如 /usr/lib中。您可以使用 ln 命令来创建软链接。 sudo ln -s /path/to/your/library/libmyserver.so /usr/lib/libmyserver.so4、设置系统配置文件 /etc/ld.so.conf.d/ 目录在 Linux 系统中用于存放动态链接器的配置文件这些文件告诉系统在哪里可以找到动态库。当系统需要加载一个共享库时它会查看 /etc/ld.so.conf 文件这个文件通常包含了指向 /etc/ld.so.conf.d/ 目录下所有配置文件的指令以及 /etc/ld.so.conf.d/ 下的所有 .conf 文件以确定库文件的搜索路径。 如果有一个自定义的库文件路径并且希望在系统启动或运行任何需要该库的程序时动态链接器都能找到这个库我们可以创建一个新的 .conf 文件在 /etc/ld.so.conf.d/ 目录下添加我的库文件所在的目录路径。 添加完成后运行 ldconfig 命令以更新动态链接器的缓存。这个命令会读取 /etc/ld.so.conf 和 /etc/ld.so.conf.d/ 下的所有配置文件并构建动态链接器的缓存。 删除配置文件后ldd myexe就not found。 五、动静态库的比较
首先我们对它们的使用的特点进行对比
编译和链接过程的比较 静态库在编译阶段静态库会被完全链接到可执行文件中多个程序使用时会有多份代码所以代码体积会增大。这意味着当静态库更新时所有使用它的程序都需要重新编译和链接。动态库在编译阶段程序只与动态库进行符号链接并不将库的内容直接包含到可执行文件中。在运行时操作系统动态地负责加载和链接动态库。因此当动态库更新时只需要替换库文件而不需要重新编译和链接程序。静态链接表示静态性在编译链接之后库中需要的资源已经在可执行程序中了也就是静态存在没有依赖性了。而动态链接表示实时性在运行的时候载入需要的资源必须在运行的时候提供需要的动态库有依赖性运行时候没有找到库就不能运行了。 运行时性能的比较 静态库由于静态库在编译时被完全链接到可执行文件中因此程序的启动速度通常较快。但是由于所有依赖的库都被包含在内可执行文件可能会变得较大从而占用更多的内存和磁盘空间。动态库动态库在运行时被加载到内存中因此程序的启动速度可能会稍慢一些。但是由于多个程序可以共享同一个动态库因此可以减少内存和磁盘空间的占用。此外动态库支持延迟加载即只在需要时才加载库中的代码和数据这有助于进一步提高程序的性能。 适用场景的分析 静态库适用于以下场景 程序只使用库中的部分函数且这些函数的大小比较小。库的版本很少更改且不需要与其他库进行交互。程序需要在没有库文件的情况下运行或者需要将程序和库打包成单个可执行文件。 动态库适用于以下场景 库的大小较大或者它包含在多个程序中。库的版本需要经常更改或者需要与其他库进行交互。需要在运行时加载库例如插件。动态库在运行时并不会全部加载到内存中而是以需要的方式进行加载。这种延迟加载可以帮助减少内存占用并提高应用程序的性能。
综上所述动静态库各有优缺点适用于不同的场景和需求。在选择使用哪种库时需要根据具体的项目需求和环境条件进行权衡和考虑。
那么若动态库和静态库同时存在会发生什么呢 我们可以分析出如果同时有动态库和静态库默认使用动态库。 若此时要使用静态链接需要加上 -static选项。
下面我们把动态库移走观察只有静态库的情况下会发生什么
此时我们移走了动态库只剩下了静态库。那么只能对该库进行静态链接但是程序不一定整体是静态链接的。 如果只有动态库默认只能动态链接。若静态链接会报错。
如果同时提供动态库和静态库gcc默认使用动态库。如果想使用静态链接。需要加 static使用。如果只有静态库那我们的可执行程序只能进行静态链接但是程序不一定整体是静态链接的。如果只有动态库默认只能动态链接若非要静态链接会发生链接报错。
- 上一篇: 网站后台登录模板html班级网站制作模板
- 下一篇: 网站后台服务器内部错误可以免费发广告的网站
相关文章
-
网站后台登录模板html班级网站制作模板
网站后台登录模板html班级网站制作模板
- 技术栈
- 2026年03月21日
-
网站后台登录界面下载保定市住房保障和城乡建设局网站
网站后台登录界面下载保定市住房保障和城乡建设局网站
- 技术栈
- 2026年03月21日
-
网站后台登陆不上去顺德品牌网站建设优惠
网站后台登陆不上去顺德品牌网站建设优惠
- 技术栈
- 2026年03月21日
-
网站后台服务器内部错误可以免费发广告的网站
网站后台服务器内部错误可以免费发广告的网站
- 技术栈
- 2026年03月21日
-
网站后台更新 前台看不到wordpress 弹窗登陆
网站后台更新 前台看不到wordpress 弹窗登陆
- 技术栈
- 2026年03月21日
-
网站后台更新 前台为啥没反应学校网站建设论文
网站后台更新 前台为啥没反应学校网站建设论文
- 技术栈
- 2026年03月21日
