精华内容
下载资源
问答
  • 2021-01-17 16:42:01

    静态文件和动态文件

    1.文件存放在块设备(磁盘)的文件系统中的文件中,我们称之为静态文件。文件存放在内存中,我们称之为动态文件。

    2.当程序open一个文件时linux内核会做以下操作:首先内核会建立一个打开文件的数据结构(包含文件描述符,节点信息等),记录我们打开的文件。然后会向内存申请一段内存,并且将静态文件里面的内容从块设备读取到内核中特定地址管理存放。

    3 当打开文件后,对文件进行读写操作,都是在内存中这一份动态文件进行操作,而不是针对静态文件。此时修改动态文件的内容,并不会影响静态文件里面的内容,两者是不同步的。当close文件时,close内部的内核会将动态文件里面的内容更新到块设备的静态文件中。

    4 为什么要这样设计?不直接对块设备进行操作?
    因为块设备的读写速度相对内存慢,是按块为单位进行操作,不灵活。而内存是按字节为单位进行操作的,而且可以随机操作,很灵活。

    更多相关内容
  • Linux动态和静态

    万次阅读 多人点赞 2021-10-28 10:56:35
    文章目录动静态库的基本原理认识动静态库动静态库各自的特征静态库的打包与使用打包使用动态库的打包与使用打包使用 动静态库的基本原理 动静态库的本质是可执行程序的“半成品”。 我们都知道,一堆源文件...

    动静态库的基本原理

    动静态库的本质是可执行程序的“半成品”。

    我们都知道,一堆源文件和头文件最终变成一个可执行程序需要经历以下四个步骤:

    1. 预处理: 完成头文件展开、去注释、宏替换、条件编译等,最终形成xxx.i文件。
    2. 编译: 完成词法分析、语法分析、语义分析、符号汇总等,检查无误后将代码翻译成汇编指令,最终形成xxx.s文件。
    3. 汇编: 将汇编指令转换成二进制指令,最终形成xxx.o文件。
    4. 链接: 将生成的各个xxx.o文件进行链接,最终形成可执行程序。

    例如,用test1.c、test2.c、test3.c、test4.c以及main1.c形成可执行文件,我们需要先得到各个文件的目标文件test1.o、test2.o、test3.o、test4.o以及main1.o,然后再将这写目标文件链接起来,最终形成一个可执行程序。
    在这里插入图片描述
    如果我们在另一个项目当中也需要用到test1.c、test2.c、test3.c、test4.c和项目的main2.c或者main3.c分别形成可执行程序,那么可执行程序生成的步骤也是一样的。
    在这里插入图片描述
    而实际上,对于可能频繁用到的源文件,比如这里的test1.c、test2.c、test3.c、test4.c,我们可以将它们的目标文件test1.o、test2.o、test3.o、test4.o进行打包,之后需要用到这四个目标文件时就可以之间链接这个包当中的目标文件了,而这个包实际上就可以称之为一个库。
    在这里插入图片描述
    实际上,所有库本质都是一堆目标文件(xxx.o)的集合,库的文件当中并不包含主函数而只是包含了大量的方法以供调用,所以说动静态库本质是可执行程序的“半成品”。

    认识动静态库

    在Linux下创建文件编写以下代码,并生成可执行程序。

    #include <stdio.h>
    
    int main()
    {
    	printf("hello world\n"); //库函数
    	return 0;
    }
    

    这是最简单的代码,运行结果大家也都知道,就是hello world。
    在这里插入图片描述

    下面我们就通过这份简单的代码来认识一下动静态库

    在这份代码当中我们可以通过调用printf输出hello world,主要原因是gcc编译器在生成可执行程序时,将C标准库也链接进来了。

    在Linux下,我们可以通过ldd 文件名来查看一个可执行程序所依赖的库文件。
    在这里插入图片描述
    这其中的libc.so.6就是该可执行程序所依赖的库文件,我们通过ls命令可以发现libc.so.6实际上只是一个软链接。
    在这里插入图片描述
    实际上该软链接的源文件libc-2.17.solibc.so.6在同一个目录下,为了进一步了解,我们可以通过file 文件名命令来查看libc-2.17.so的文件类型。
    在这里插入图片描述
    此时我们可以看到,libc-2.17.so实际上就是一个共享的目标文件库,准确来说,这还是一个动态库。

    • 在Linux当中,以.so为后缀的是动态库,以.a为后缀的是静态库。
    • 在Windows当中,以.dll为后缀的是动态库,以.lib为后缀的是静态库。

    这里可执行程序所依赖的libc.so.6实际上就是C动态库,当我们去掉一个动静态库的前缀lib,再去掉后缀.so或者.a及其后面的版本号,剩下的就是这个库的名字。

    而gcc/g++编译器默认都是动态链接的,若想进行静态链接,可以携带一个-static选项。

    [cl@VM-0-15-centos testlib]$ gcc -o mytest-s mytest.c -static
    

    在这里插入图片描述
    此时生成的可执行程序就是静态链接的了,可以明显发现静态链接生成的可执行程序的文件大小,比动态链接生成的可执行程序的文件大小要大得多。

    静态链接生成的可执行程序并不依赖其他库文件,此时当我们使用ldd 文件名命令查看该可执行程序所依赖的库文件时就会看到以下信息。
    在这里插入图片描述
    此外,当我们分别查看动静态链接生成的可执行程序的文件类型时,也可以看到它们分别是动态链接和静态链接的。
    在这里插入图片描述

    动静态库各自的特征

    静态库

    静态库是程序在编译链接的时候把库的代码复制到可执行文件当中的,生成的可执行程序在运行的时候将不再需要静态库,因此使用静态库生成的可执行程序的大小一般比较大。

    优点:

    • 使用静态库生成可执行程序后,该可执行程序就可以独自运行,不再需要库了。

    缺点:

    • 使用静态库生成可执行程序会占用大量空间,特别是当有多个静态程序同时加载而这些静态程序使用的都是相同的库,这时在内存当中就会存在大量的重复代码。

    动态库

    动态库是程序在运行的时候才去链接相应的动态库代码的,多个程序共享使用库的代码。一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。

    在可执行文件开始运行前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接。动态库在多个程序间共享,节省了磁盘空间,操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
    在这里插入图片描述
    优点:

    • 节省磁盘空间,且多个用到相同动态库的程序同时运行时,库文件会通过进程地址空间进行共享,内存当中不会存在重复代码。

    缺点:

    • 必须依赖动态库,否则无法运行。

    静态库的打包与使用

    为了更容易理解,下面演示动静态库的打包与使用时,都以下面的四个文件为例,其中两个源文件add.csub.c,两个头文件add.hsub.h

    add.h当中的内容如下:

    #pragma once
    
    extern int my_add(int x, int y);
    

    add.c当中的内容如下:

    #include "add.h"
    
    int my_add(int x, int y)
    {
    	return x + y;
    }
    

    sub.h当中的内容如下:

    #pragma once
    
    extern int my_sub(int x, int y);
    

    sub.c当中的内容如下:

    #include "sub.h"
    
    int my_sub(int x, int y)
    {
    	return x - y;
    }
    

    代码内容都非常简单,我就不做过多的阐述了。

    打包

    下面我们就利用这四个文件打包生成一个静态库:
    在这里插入图片描述

    第一步:让所有源文件生成对应的目标文件

    在这里插入图片描述

    第二步:使用ar命令将所有目标文件打包为静态库

    ar命令是gnu的归档工具,常用于将目标文件打包为静态库,下面我们使用ar命令的-r选项和-c选项进行打包。

    • -r(replace):若静态库文件当中的目标文件有更新,则用新的目标文件替换旧的目标文件。
    • -c(create):建立静态库文件。
    [cl@VM-0-15-centos static]$ ar -rc libcal.a add.o sub.o
    

    在这里插入图片描述
    此外,我们可以用ar命令的-t选项和-v选项查看静态库当中的文件。

    • -t:列出静态库中的文件。
    • -v(verbose):显示详细的信息。
    [cl@VM-0-15-centos static]$ ar -tv libcal.a
    

    在这里插入图片描述

    第三步:将头文件和生成的静态库组织起来

    当我们把自己的库给别人用的时候,实际上需要给别人两个文件夹,一个文件夹下面放的是一堆头文件的集合,另一个文件夹下面放的是所有的库文件。

    因此,在这里我们可以将add.hsub.h这两个头文件放到一个名为include的目录下,将生成的静态库文件libcal.a放到一个名为lib的目录下,然后将这两个目录都放到mathlib下,此时就可以将mathlib给别人使用了。
    在这里插入图片描述

    使用Makefile

    当然,我们可以将上述所要执行的命令全部写到Makefile当中,后续当我们要生成静态库以及组织头文件和库文件时就可以一步到位了,不至于每次重新生成的时候都要敲这么多命令,这也体现了Makefile的强大。
    使用Makefile。。。
    编写Makefile后,只需一个make就能生成所有源文件对应的目标文件进而生成静态库。
    在这里插入图片描述
    一个make output就能将头文件和静态库组织起来。
    在这里插入图片描述

    使用

    创建源文件main.c,编写下面这段简单的程序来尝试使用我们打包好的静态库。

    #include <stdio.h>
    #include <add.h>
    
    int main()
    {
    	int x = 20;
    	int y = 10;
    	int z = my_add(x, y);
    	printf("%d + %d = %d\n", x, y, z);
    	return 0;
    }
    

    现在该目录下就只有main.c和我们刚才打包好的静态库。
    在这里插入图片描述

    方法一:使用选项

    此时使用gcc编译main.c生成可执行程序时需要携带三个选项:

    • -I:指定头文件搜索路径。
    • -L:指定库文件搜索路径。
    • -l:指明需要链接库文件路径下的哪一个库。
    [cl@VM-0-15-centos project]$ gcc main.c -I./mathlib/include -L./mathlib/lib -lcal
    

    在这里插入图片描述
    此时就可以成功使用我们自己打包的库文件并生成可执行程序。
    在这里插入图片描述
    说明一下:

    1. 因为编译器不知道你所包含的头文件add.h在哪里,所以需要指定头文件的搜索路径。
    2. 因为头文件add.h当中只有my_add函数的声明,并没有该函数的定义,所以还需要指定所要链接库文件的搜索路径。
    3. 实际中,在库文件的lib目录下可能会有大量的库文件,因此我们需要指明需要链接库文件路径下的哪一个库。库文件名去掉前缀lib,再去掉后缀.so或者.a及其后面的版本号,剩下的就是这个库的名字。
    4. -I-L-l这三个选项后面可以加空格,也可以不加空格。

    方法二:把头文件和库文件拷贝到系统路径下

    既然编译器找不到我们的头文件和库文件,那么我们直接将头文件和库文件拷贝到系统路径下不就行了。

    [cl@VM-0-15-centos project]$ sudo cp mathlib/include/* /usr/include/
    
    [cl@VM-0-15-centos project]$ sudo cp mathlib/lib/libcal.a /lib64/
    

    在这里插入图片描述
    需要注意的是,虽然已经将头文件和库文件拷贝到系统路径下,但当我们使用gcc编译main.c生成可执行程序时,还是需要指明需要链接库文件路径下的哪一个库。
    在这里插入图片描述
    此时才能成功使用我们自己打包的库文件并生成可执行程序。
    在这里插入图片描述

    为什么之前使用gcc编译的时候没有指明过库名字?

    因为我们使用gcc编译的是C语言,而gcc就是用来编译C程序的,所以gcc编译的时候默认就找的是C库,但此时我们要链接的是哪一个库编译器是不知道的,因此我们还是需要使用-l选项,指明需要链接库文件路径下的哪一个库。

    扩展:
    实际上我们拷贝头文件和库文件到系统路径下的过程,就是安装库的过程。但并不推荐将自己写的头文件和库文件拷贝到系统路径下,这样做会对系统文件造成污染。

    动态库的打包与使用

    打包

    动态库的打包相对于静态库来说有一点点差别,但大致相同,我们还是利用这四个文件进行打包演示:
    在这里插入图片描述

    第一步:让所有源文件生成对应的目标文件

    此时用源文件生成目标文件时需要携带-fPIC选项:

    • -fPIC(position independent code):产生位置无关码。

    在这里插入图片描述
    说明一下:

    1. -fPIC作用于编译阶段,告诉编译器产生与位置无关的代码,此时产生的代码中没有绝对地址,全部都使用相对地址,从而代码可以被加载器加载到内存的任意位置都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
    2. 如果不加-fPIC选项,则加载.so文件的代码段时,代码段引用的数据对象需要重定位,重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的拷贝,并且每个拷贝都不一样,取决于这个.so文件代码段和数据段内存映射的位置。
    3. 不加-fPIC编译出来的.so是要在加载时根据加载到的位置再次重定位的,因为它里面的代码BBS位置无关代码。如果该.so文件被多个应用程序共同使用,那么它们必须每个程序维护一份.so的代码副本(因为.so被每个程序加载的位置都不同,显然这些重定位后的代码也不同,当然不能共享)。
    4. 我们总是用-fPIC来生成.so,但从来不用-fPIC来生成.a。但是.so一样可以不用-fPIC选项进行编译,只是这样的.so必须要在加载到用户程序的地址空间时重定向所有表目。

    第二步:使用-shared选项将所有目标文件打包为动态库

    与生成静态库不同的是,生成动态库时我们不必使用ar命令,我们只需使用gcc的-shared选项即可。

    [cl@VM-0-15-centos dynamic]$ gcc -shared -o libcal.so add.o sub.o
    

    在这里插入图片描述

    第三步:将头文件和生成的动态库组织起来

    与生成静态库时一样,为了方便别人使用,在这里我们可以将add.hsub.h这两个头文件放到一个名为include的目录下,将生成的动态库文件libcal.so放到一个名为lib的目录下,然后将这两个目录都放到mlib下,此时就可以将mlib给别人使用了。
    在这里插入图片描述

    使用Makefile

    当然,生成动态库也可以将上述所要执行的命令全部写到Makefile当中,后续当我们要生成动态库以及组织头文件和库文件时就可以一步到位了。
    在这里插入图片描述
    编写Makefile后,只需一个make就能生成所有源文件对应的目标文件进而生成动态库。
    在这里插入图片描述
    一个make output就能将头文件和动态库组织起来。
    在这里插入图片描述

    使用

    我们还是用刚才使用过的main.c来演示动态库的使用。

    #include <stdio.h>
    #include <add.h>
    
    int main()
    {
    	int x = 20;
    	int y = 10;
    	int z = my_add(x, y);
    	printf("%d + %d = %d\n", x, y, z);
    	return 0;
    }
    

    现在该目录下就只有main.c和我们刚才打包好的动态库。
    在这里插入图片描述
    说明一下,使用该动态库的方法与刚才我们使用静态库的方法一样,我们既可以使用 -I-L-l这三个选项来生成可执行程序,也可以先将头文件和库文件拷贝到系统目录下,然后仅使用-l选项指明需要链接的库名字来生成可执行程序,下面我们仅以第一种方法为例进行演示。

    此时使用gcc编译main.c生成可执行程序时,需要用-I选项指定头文件搜索路径,用-L选项指定库文件搜索路径,最后用-l选项指明需要链接库文件路径下的哪一个库。

    [cl@VM-0-15-centos project]$ gcc main.c -I./mlib/include -L./mlib/lib -lcal
    

    在这里插入图片描述
    与静态库的使用不同的是,此时我们生成的可执行程序并不能直接运行。
    在这里插入图片描述
    需要注意的是,我们使用-I-L-l这三个选项都是在编译期间告诉编译器我们使用的头文件和库文件在哪里以及是谁,但是当生成的可执行程序生成后就与编译器没有关系了,此后该可执行程序运行起来后,操作系统找不到该可执行程序所依赖的动态库,我们可以使用ldd命令进行查看。
    在这里插入图片描述
    可以看到,此时可执行程序所依赖的动态库是没有被找到的。

    解决该问题的方法有以下三个:

    方法一:拷贝.so文件到系统共享库路径下

    既然系统找不到我们的库文件,那么我们直接将库文件拷贝到系统共享的库路径下,这样一来系统就能够找到对应的库文件了。

    [cl@VM-0-15-centos project]$ sudo cp mlib/lib/libcal.so /lib64
    

    在这里插入图片描述
    可执行程序也就能够顺利运行了。
    在这里插入图片描述

    方法二:更改LD_LIBRARY_PATH

    LD_LIBRARY_PATH是程序运行动态查找库时所要搜索的路径,我们只需将动态库所在的目录路径添加到LD_LIBRARY_PATH环境变量当中即可。

    [cl@VM-0-15-centos project]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/cl/BasicIO/testlib/project/mlib/lib
    

    在这里插入图片描述
    此时我们再用ldd命令查看该可执行程序就会发现,系统现在就可以找到该可执行程序所依赖的动态库了。
    在这里插入图片描述
    现在我们也就能正常运行该可执行程序了。
    在这里插入图片描述

    方法三:配置/etc/ld.so.conf.d/

    我们可以通过配置/etc/ld.so.conf.d/的方式解决该问题,/etc/ld.so.conf.d/路径下存放的全部都是以.conf为后缀的配置文件,而这些配置文件当中存放的都是路径,系统会自动在/etc/ld.so.conf.d/路径下找所有配置文件里面的路径,之后就会在每个路径下查找你所需要的库。我们若是将自己库文件的路径也放到该路径下,那么当可执行程序运行时,系统就能够找到我们的库文件了。

    首先将库文件所在目录的路径存入一个以.conf为后缀的文件当中。
    在这里插入图片描述
    然后将该.conf文件拷贝到/etc/ld.so.conf.d/目录下。
    在这里插入图片描述
    但此时我们用ldd命令查看可执行程序时,发现系统还是没有找到该可执行程序所依赖的动态库。
    在这里插入图片描述
    这时我们需要使用ldconfig命令将配置文件更新一下,更新之后系统就可以找到该可执行程序所依赖的动态库了。

    [cl@VM-0-15-centos project]$ sudo ldconfig
    

    在这里插入图片描述
    而此时我们也就可以正常运行该可执行程序了。
    在这里插入图片描述

    展开全文
  • iOS动态和静态库的运用

    千次阅读 2022-03-04 09:25:52
    库分为静态和动态库两种。 静态库:链接时完整地拷贝至可执行文件中,使可执行文件体积变大。如果多个APP都使用了同一个静态库,那么每个APP都会拷贝一份。 动态库:链接时不拷贝至可执行文件中,可执行文件只会...

    概念认识

    什么是库

    • 库是共享程序代码的方式,库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。在开发过程中,一些核心技术或者常用框架,出于安全性和稳定性的考虑,不想被外界知道,所以会把核心代码打包成库,只暴露出头文件以供使用。
    • 库分为静态库和动态库两种。
      • 静态库:链接时完整地拷贝至可执行文件中,使可执行文件体积变大。如果多个APP都使用了同一个静态库,那么每个APP都会拷贝一份。
      • 动态库:链接时不拷贝至可执行文件中,可执行文件只会存储指向动态库的引用。程序运行时由系统动态加载到内存中,系统只会加载一次, 多个APP共用一份。
    • 静态库的存在形式有两种:.a静态库、.framework静态库
    • 动态库的存在形式有两种:.dylib动态库、系统的.framework动态库

    系统的.framework是系统SDK库,有Foundation.framework、UIKit.framework、MapKit.framework等。由于苹果不开源,每个框架只提供了接口(.h文件),所有实现(.m文件或.c/.cpp文件)编译在一个.framework二进制文件中。

    苹果把所有系统的.framework二进制文件统一打包到一个共享缓存文件中(dyld shared cache),共享缓存文件存储在手机路径(需要越狱才能找到):/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armX。X代表ARM处理器指令集架构。

    动态链接器(dyld)存储在手机路径:/usr/lib/dyld,用于在APP运行时,链接APP和系统的.framework。

    两种.framework区别

    • 静态库的形式包含.a和.framework两种形式,动态库的形式包含.dylib和系统的.framework两种形式。
      动态库的.framework是系统SDK才有的库,而我们自己创建出来的.framework都是静态库

    静态库中.a与.framework的区别

    • .a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。
      .a文件不能直接使用,需要.h文件配合。
      .framework文件可以直接使用,因为本身包含了.h文件和资源文件。
      .framework = .a + .h + sorrceFile(资源文件)

    静态库的优点

    • 实现程序的模块化,将固定的业务模块化成静态库。
    • 方便共享代码,即可以和别人分享你的代码库,但别人又看不到你代码的实现。
    • 开发第三方sdk的需要,例如两个公司之间业务交流,不可能把源代码都发送给另一个公司,这时候将私密内容打包成静态库,别人只能调用接口,而不能知道其中实现的细节。

    编译链接

    • 源代码转成目标文件的过程:
      源代码先经过预处理器进行宏替换、删除注释等工作,得到.i文件,然后编译器对.i文件进行编译,编译成汇编语言程序(扩展名.s或.asm),之后再将汇编语言程序编译成机器指令(0和1组成),得到目标文件(扩展名.o)。
    • 编译器和链接器处理流程:
      源代码(.c或.cpp)→编译器→目标文件(.object)→链接器(+静态库)→可执行文件(.exe或Mach-O)
    • 链接器作用:
      对于静态库,在编译链接时把多个目标文件和所用到的库文件链接在一起形成一个完整的可执行文件,可执行文件会比较大,但程序运行时就不需要库了。
      对于动态库,在编译链接时把多个目标文件链接成可执行文件,但不会把库文件加入到该可执行文件中,而是在程序运行时链接库文件。

    静态库制作

    制作.a静态库

    • .a文件是一种静态库,a是archive(归档)的缩写,它是由多个.o文件归档而成
    • 新建工程,iOS --> Framework & Library --> Cocoa Touch Static Library
    这里注意由于创建的是Static Library,Build Settings搜索linking,Mach-O Type默认为Static Library。
    - 删除不需要的类,如StaticLibraryTool类,创建我们所需的类,如下:
    - 添加需要公开的头文件
    - 设置静态库需要支持的最低系统版本
    - 修改配置 Active Architecture Only修改为NO,否则生成的静态库就只支持当前选择设备的架构。
    - 接下来可以开始编译生成.a文件了。 设备选择Generic iOS Device,即通用型真机,然后command+B编译,在工程Products目录下生成.a文件,右键Show in Finder找到.a文件所在路径,图示Products目录下的libStaticLibraryTool.a从红色(红色表示文件不存在)变成了黑色(黑色表示文件存在),此时表示提供真机使用的静态库编译成功。
    接着设备切换选择任一模拟器,command+B编译,此时提供模拟器使用的静态库编译成功,如下:
    这两个.a文件要么只支持真机,要么只支持模拟器,如果想真机和模拟器都能使用该静态库,需要将二者合成为一个静态库,可用终端命令实现: ```objc lipo -create 第一个.a文件路径 第二个.a文件路径 -output 最终的.a文件路径 ```

    合成为一个静态库后,我们可查看合成后的静态库支持的架构,用命令:lipo -info xxx.a,看真机和模拟器架构是否都支持。结果如下:

    "i386 x86_64"是模拟器架构,"armv7 arm64"是真机架构,说明该静态库两者都支持。 静态库支持哪些架构?
    模拟器架构
        iPhone4s ~ 5/5c : i386
        iPhone5s以后机型 : x86_64
    真机架构
        3GS~4s : armv7
        5/5c : armv7s(armv7兼容armv7s)
        5s ~ iPhoneX : arm64
        iPhone XS以后机型 : arm64e
    
    • 如何使用.a静态库?
      把.a文件和公开的头文件放入一个文件夹,命名为libStaticLibraryTool。将libStaticLibraryTool文件夹添加到需要使用的工程中,如下:

    libStaticLibraryTool.a添加到工程后,
    Build Pases->Link Binary With Libraries 和 General->Frameworks, Libraries, and Embedded Content都会自动引入libStaticLibraryTool.a。
    Build Settings->Library Search Paths也会自动设置.a文件路径,如:$(PROJECT_DIR)/DemoA/libStaticLibraryTool。
    由于静态库中使用了OC的分类(Category),OC链接器只会为类建立符号表,不会为分类建立符号表,导致函数调用时(运行时)找不到分类的符号表,无法获取函数地址,函数调用失败。
    解决办法:设置Other Linker Flags的值为-ObjC,为分类建立符号表。
    注意:如果不做该设置,项目中引用该库,访问该库的Category接口时会崩溃

    最后我们便能在项目中引入头文件,使用.a静态库的功能了,如下:
    - Xcode13制作静态库,左侧的Products目录不见了,其实Products是存在的,只是没有展示出来。 解决方式:对.xcodeproj右键“显示包内容”,打开project.pbxproj,command+f搜索mainGroup,复制mainGroup的值,将其粘贴到productRefGroup的值上,使两者保持一致,这样工程左侧的Products目录就显示出来了。

    制作.framework静态库

    • 新建工程时选择Framework
    该Framework默认是Dynamic Library(动态库),我们需要将其设置成静态库:Build Settings搜索mach,Mach-O Type选择Static Library。 往工程中添加Person类和UIImage+Extension类,StaticLibraryTool.h中引入Person类和UIImage+Extension类的头文件,推荐用包含静态库名的尖括号,指明引入的是哪个静态库的头文件:
    Person.h和UIImage+Extension.h需要暴露出来,这两个头文件默认在TARGETS->Build Phases->Headers的Project中,将它们拖拽到Headers的Public中,如下:
    设置Build Settings中的Active Architecture Only为NO,iOS Deployment Target的最低版本为iOS 9.0,然后command+B,编译生成.framework静态库。 - 如何使用.framework静态库? 使用时,将StaticLibraryTool.framework拖入到需要使用的工程中。 Build Settings->Other Linker Flags设置-ObjC,以便编译器能加载OC的Category(若不配置这个,访问Category的接口时程序会崩溃)。 由于静态库StaticLibraryTool.h中引入的头文件带上了静态库名作为路径,即如下方式 ```c #import

    实现静态库的注意事项

    • 无论是.a静态库还是.framework静态库,我们需要的都是二进制文件+.h文件+资源文件,不同的是,.a本身只是二进制文件,需要配上.h文件和资源文件才能使用,而.framework本身已经包含了二进制文件、.h和资源文件,可以直接使用。
    • 图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。新建一个文件夹,把它改名为.bundle,右键->显示包内容,之后就可以向其中添加资源文件。
    • 把category打成静态库,在使用静态库的工程中,调用category中的方法时会报找不到该方法的错误(selector not recognized),解决办法是:在使用静态库的工程中配置Build Settings->Other Linker Flags的值为-ObjC。
    • 如果一个静态库很复杂,需要暴露的.h文件比较多,则可以在静态库的内部创建一个.h文件(这个.h文件的名字一般和静态库的名字相同)统一管理,把所有需要暴露出来的.h文件都集中放在这个.h文件中,这样使用时可以只引入该.h文件。

    👉🏻项目地址:iOS-StaticLibrary
    如果文章和项目对你有帮助,还请给个Star⭐️,你的Star⭐️是我持续输出的动力,谢谢啦😘

    展开全文
  • tomcat动态部署和静态部署

    千次阅读 2016-06-22 10:09:10
    一、静态部署 1、直接将web项目文件件拷贝到webapps 目录中 Tomcat的Webapps目录是Tomcat默认的应用目录,当服务器启动时,会加载所有这个目录下的应用。所以可以将JSP程序打包成一个 war包放在目录下,服务器会...
    一、静态部署
    1、直接将web项目文件件拷贝到webapps 目录中
    Tomcat的Webapps目录是Tomcat默认的应用目录,当服务器启动时,会加载所有这个目录下的应用。所以可以将JSP程序打包成一个 war包放在目录下,服务器会自动解开这个war包,并在这个目录下生成一个同名的文件夹。一个war包就是有特性格式的jar包,它是将一个web程序的所有内容进行压缩得到。具体如何打包,可以使用许多开发工具的IDE环境,如Eclipse等。也可以用 cmd 命令:jar -cvf mywar.war myweb 
    webapps这个默认的应用目录也是可以改变。打开Tomcat的conf目录下的server.xml文件,找到下面内容:
    <Host name="localhost" appBase="webapps"
    unpackWARs="true" autoDeploy="true"
    xmlValidation="false" xmlNamespaceAware="false">
    将appBase修改即可。 
    2、在server.xml中指定 
    在Tomcat的配置文件中,一个Web应用就是一个特定的Context,可以通过在server.xml中新建Context里部署一个JSP应用程序。打开server.xml文件,在Host标签内建一个Context,内容如下。

    在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加: 
    <Context path="/hello" docBase="D:\ workspace\hello\WebRoot" debug="0" privileged="true"> 
    </Context>
    或者
    <Context path="/myapp" reloadable="true" docBase="D:\myapp" workDir="D:\myapp\work"/>
    或者
    <Context path="/sms4" docBase="D:\workspace\sms4\WebRoot"/>

    说明:
    path是虚拟路径;
    docBase 是应用程序的物理路径;
    workDir 是这个应用的工作目录,存放运行时生成的与这个应用相关的文件;

    debug 则是设定debug level, 0表示提供最少的信息,9表示提供最多的信息
    privileged设置为true的时候,才允许Tomcat的Web应用使用容器内的Servlet
    reloadable 如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes目录的变化,自动装载新的应用程序,可以在不重起tomcat的情况下改变应用程序,实现热部署
    antiResourceLocking和antiJARLocking 热部署是需要配置的参数,默认false避免更新了某个webapp,有时候Tomcat并不能把旧的webapp完全删除,通常会留下WEB-INF/lib下的某个jar包,必须关闭Tomcat才能删除,这就导致自动部署失败。设置为true,Tomcat在运行对应的webapp时,会把相应的源文件和jar文件复制到一个临时目录里。
    3、创建一个Context文件 
    在conf目录中,新建 Catalina\localhost目录,在该目录中新建一个xml文件,名字不可以随意取,要和path后的那个名字一致,按照下边这个path的配置,xml的名字应该就应该是hello(hello.xml),该xml文件的内容为:
    <Context path="/hello" docBase="E:\workspace\hello\WebRoot" debug="0" privileged="true"></Context>

    tomcat自带例子如下:
    <Context docBase="${catalina.home}/server/webapps/host-manager"
    privileged="true" antiResourceLocking="false" antiJARLocking="false">
    </Context>
    这个例子是tomcat自带的,编辑的内容实际上和第二种方式是一样的,其中这xml文件名字就是访问路径,这样可以隐藏应用的真实名字。
    4、注意:
    删除一个Web应用同时也要删除webapps下相应的文件夹和server.xml中相应的Context,还要将Tomcat的conf\catalina\localhost目录下相应的xml文件删除,否则Tomcat仍会去配置并加载。。。
    二、动态部署
        动态部署是指可以在服务器启动之后部署web应用程序,而不用重新启动服务器。动态部署要用到服务器提供的manager.war文件,如果在 $CATALINA_HOME\webapps\下没有该文件,你必须去重新下载tomcat,否则不能完成以下的功能。要想使用该管理程序必须首先编辑$CATALINA_HOME\conf\tomcat-users.xml文件,内容如下:关于这个文件的更多内容,请参考Java Web应用程序的安全模型二

    然后在浏览器中键入如下地址:
    http://localhost:8080/ 应该看到一个漂亮的加菲猫了吧。点击左边的Tomcat Manager链接,提示输入用户名和密码,本文都是coresun,然后可以看到以下页面:

    在Context Path(option):中输入/Pet
    XML Configration file URL中要指定一个.xml文件,比如我们在F:\下建立一个Pet.xml文件,内容如下:
    docBase不用写了,因为在下一个文本框中填入。或者更简单点,这个文本框什么都不填。
    在WAR or Directory URL:中键入F:\PetWet或者F:\Pet.war都可以,然后点击Deploy按钮,看看上面是不是已经看到了你web应用程序,名字就是你Context Path(option):中的名字。

    如果你部署.war文件还有更加简单的方式,下面还有个Select WAR file uploae点击浏览选择.war文件,然后点击Deploy也可以。


    展开全文
  • 前端下载静态文件动态文件

    千次阅读 2019-06-14 16:20:01
    前端下载静态文件及动态文件静态文件动态文件前端后端 静态文件 <a href="doc/use_document.pdf" download="使用文档.pdf"><Button type="primary" icon="ios-download-outline" style="margin-right:10px;...
  • CMake教程(一)- 添加库文件什么是库文件如何在CMake中添加库文件 什么是库文件 如何在CMake中添加库文件
  • .c或.cpp文件生成可执行文件.exe分为两个过程,即编译过程链接过程。 编译是把文本形式源代码翻译为机器语言形式的目标文件的过程。 链接是把目标文件、操作系统的启动代码用到的库文件进行组织,形成最终生成...
  • 其实就是动态包含和静态包含的区别: 1. 两者格式不同,静态包含:<%@ include file=“文件” %>,而动态包含:。 2. 包含时间不同,静态包含是先将几个文件合并,然后再被编译,缺点就是如果含有相同的标签,...
  • 静态链接和动态链接 1.动态库 1.1 分类 windows下:后缀为.dll的文件动态库 linux下:后缀为.so,前缀为lib的文件动态库 1.2 生成动态库 命令:gcc/g++   必选项的命令行参数: -shared==>...
  • gcc MakeFile文件引用静态库与动态库的区别makefile文件引用库路径,如下: LIB_PATH += -L路径 makefile文件引用静态库/动态库,如下: LIBS += -l库 (这的库是去掉lib,.a, .so剩余部分,如libaaa.so 这写...
  • 【SpringBoot】47、SpringBoot中如何静态加载配置文件

    万次阅读 多人点赞 2021-03-24 22:09:01
    application.yml 或 application.properties,我们可以通过 @ConfigurationProperties(prefix = “test”) 或 @Value("${test}") 等方式获取到配置内容,那有的时候我们需要通过静态的方式读取配置文件的内容,这种...
  • 静态网页和动态网页的区别

    千次阅读 2019-06-12 11:07:40
    静态网页和动态网页的区别 静态网页 静态网页是指在网站设计中,纯粹HTML(标准通用标记语言下的一个应用)格式的网页 静态网页是标准的HTML文件,它的文件扩展名是.htm、.html,可以包含文本、图像、声音、FLASH动画...
  • 动态和静态库的区别

    千次阅读 2020-09-27 15:49:47
    静态库: 在程序编译时会被连接到代码中...在程序编译并不会连接到代码中,而是在程序运行时被载入,动态库又被称为动态链接库,英文简称DLL,DLL是包含可以由多个程序使用的代码数据的库,DLL是不可执行文件。 ...
  • 静态页面和动态页面的区别

    千次阅读 2020-09-09 18:03:13
    很多不了解前端技术的人可能会认为静态页面就是一个内容固定不变,没有任何效果的页面,而动态页面则是页面非常丰富,有各种交互效果和动态效果的页面。其实这个理解是错误的。通过本篇文章的阅读,详细为大家分享...
  • 动态网页和静态网页的区别,首先要分别了解两个概念,就是什么是静态网页,什么是动态网页,并且学会区分哪些是静态哪些是动态静态网页: (1)静态网页不能简单地理解成静止不动的网页,他主要指的是网页中没有...
  •   在Linux下,可执行文件/动态文件/目标文件(可重定向文件)都是同一种文件格式,我们把它称之为ELF文件格式。   虽然它们三个都是ELF文件格式但都各有不同:   可执行文件没有section header table 。 ...
  • 将Makefile文件所在目录的.cplat目录下的.c一起编译,并且连接动态库libtest.so和静态库libtest.a,头文件存放在inc目录下。Makefile文件如下: BIN=test CC=gcc CFLAGS=-DxDEBUG STATCI_LIBS=-L. -Wl,-Bstatic -...
  • Linux-动态链接与静态链接对比(动态和静态库)

    千次阅读 多人点赞 2017-12-14 17:52:46
    一、库的基础概念: 在windows平台linux平台下都大量存在着库。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。...按照库的使用方式又可分为动态和静态库,在不同平台下...
  • .a文件:是.o文件的集合(.a 是有一系列 .o 文件通过 ar 程序打包在一起的静态库,要把它转成动态库只需先解开,生成一堆 .o 文件。) .so文件:是表示的动态库 首先 1. g++ -c -fPIC test.cpp #将cpp源文件...
  • 深入浅出静态链接和动态链接

    万次阅读 多人点赞 2018-05-06 09:24:48
    作为一名C/C++程序员,对于编译链接的过程...然后进行编译,这个过程主要是进行词法分析、语法分析语义分析等,生成*.s的汇编文件;最后进行汇编,这个过程比较简单,就是将对应的汇编指令翻译成机器指令,生成可...
  • 最近要用到的签名算法只给了一堆源码没有给库文件,api都不好调用,于是尝试着用Makefile给一堆c源码编译静态链接库文件和动态链接库文件。Makefile文件编辑的相关资料链接:...
  • nginx压缩静态文件

    千次阅读 2022-03-15 17:23:01
    nginx压缩静态文件
  • 静态库 ...这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。 动态动态库又称动态链接库英文为DLL,是Dynamic Link Library 的...
  • 动态和静态库区别

    千次阅读 2018-09-30 23:38:46
    1. 静态库:函数数据被编译进一个二进制文件(通常扩展名为.LIB)。 在编译链接可执行文件时,链接器(Linker)从库中复制这些函数数据并把它们应用程序的其它模块组合起来创建最终的可执行文件(.EXE文件)。 ...
  • django收集静态文件

    千次阅读 2022-02-07 15:21:44
    STATIC_ROOT 的路径设置为你的静态文件存放地址 STATICFILES_DIRS = [] STATIC_URL = '/static/' # 线上收集静态文件的目录 STATIC_ROOT = os.path.join(BASE_DIR,'statics') 静态文件相关配置介绍 官网地址 ...
  • 目录C/C++库文件全了解一. 前言二. 名词解释2.1. windows的静态库:xxx.lib2.2. windows的动态库:xxx.dll2.3. linux的动态库:libxxx.so2.4. linux的静态库:xxx.a三. 自己编译库3.1 编译产生windows的静态库3.1.1...
  • 按照自己的理解画的动态链接和静态链接的关系。在Linux下 应该是这样的,个人理解在Vxworks平台上是没有动态链接的,但是.o或者.out文件可以使用vxWorks的loader(loadLib)动态加载到vxworks的镜像中。 谢谢拍砖 ....
  • C++ 动态链接库和静态链接库

    千次阅读 多人点赞 2019-09-23 15:59:58
      今天对C++生成动态链接路和静态链接库非常感兴趣,必须搞定,否则都没有心情干其他事了。Let’s go~ 文章目录源程序编译链接生成文件格式预编译编译优化编译优化生成目标文件链接什么是库?动态静态的区别...
  • Unity3D中的动态字体和静态字体

    千次阅读 2019-02-26 02:54:12
    Unity3D中支持动态字体和静态字体两种格式字体,动态字体即使用TTF格式字体库,静态字体则需要自己打包字体图集。动态字体和静态字体区别在于,动态字体如果出现字体库中不存在的字体,会使用系统字体,而静态字体则...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,547,506
精华内容 619,002
关键字:

动态文件和静态文件