精华内容
下载资源
问答
  • 3.静态库生成和使用 3.1静态库的生成 4.动态库生成和使用 4.1动态库的生成 4.2 动态库的使用 4.2.1 动态链接 4.2.2 动态加载 5.工具使用 5.1 nm工具 5.2ldd命令 1.GCC编译流程 gcc可以让程序员通过它能够...

    目录

    1.GCC编译流程

    2.动态库和静态库

    3.静态库生成和使用

    3.1静态库的生成

     3.2 静态库的使用

    4.动态库生成和使用

    4.1动态库的生成

     4.2 动态库的使用

    4.2.1 动态链接

    4.2.2 动态加载

    5.工具使用

    5.1 nm工具

    5.2 ldd命令


    1.GCC编译流程

    gcc可以让程序员通过它能够更好地控制整个编译过程。

    1.预处理阶段(预处理器cpp)

    生成i的文件

    2.编译阶段(编译器egcs)

    将预处理后的文件转换成汇编语言, 生成文件.s

    3.汇编阶段(汇编器as)

    有汇编变为目标代码(机器代码)生成 .o 的文件

    4.链接阶段(链接器ld)

    连接目标代码, 生成可执行程序.exe

    如图所示:

    gcc的常用项如图:

    选项名

    作用

    -c

    通知gcc取消连接步骤,即编译源码并在最后生成目标文件

    -Dmacro

    定义指定的宏,使它能够通过源码中的#ifdef进行检验

    -E

    不经过编译预处理程序的输出而输送至标准输出

    0

    获得有关调试程序的详细信息,它不能与-o选项联合使用

    -I

    在包含文件搜索路径的起点处添加指定目录

    -l

    提示连接程序在创建最终可执行文件时包含指定的库

    -shared

    生成共享目标文件。通常用在建立共享库时。

    -static

    禁止使用共享连接。

    -O、-O2、-O3

    将优化状态打开,该选项不能与-g选项联合使用

    -O0: 不进行优化处理

    -O1或者-O: 优化生成代码。

    -O2: 进一步优化

    -O3:比 -O2 更进一步优化,包括 inline 函数

    -S

    要求编译程序生成来自源代码的汇编程序输出

    -v

    启动所有警报

    -h

    预处理文件(标头文件)

    -Wall

    在发生警报时取消编译操作,即将警报看作是错误

    -w

    禁止所有的报警

    参考:

    1.Linux基础——gcc编译、静态库与动态库(共享库)_daidaihema的博客-CSDN博客_gcc 动态库编译

    2.GCC 参数详解 | 菜鸟教程

    2.动态库和静态库

    区别如下:

    静态库

    动态库

    特点

    在链接阶段,将汇编生成的.o文件和引用库一起生成可执行文件,这个方式称之为动态连接。

    静态库:libxxxx.a

    特点:

    1.静态库对函数库的链接是放在编译时。

    2.程序在运行时与函数库再无瓜葛

    3.浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。

    动态库:libxxx.so

    1.动态库把对一些库函数的链接载入推迟到程序运行的时期。

    2.可以实现进程之间的资源共享

    3.方便程序升级。

    4.可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)

    优点

    程序在运行时与函数库没有关系

    1.动态库把对一些库函数的链接载入推迟到程序运行的时期。

    2.可以实现进程之间的资源共享

    3.方便程序升级。

    4.可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)

    缺点

    1.空间浪费

    2.静态库对程序的更新、部署和发布页会带来麻烦

    运行时候需要连接库,不存在将报错

    备注:inux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。

    參考:https://www.cnblogs.com/codingmengmeng/p/6046481.html

    3.静态库生成和使用

    3.1静态库的生成

    Linux中的静态库与动态库 - 独孤剑—宇枫 - 博客园

    步骤1.书写示例代码:如下add.cpp和mult.cpp头文件和源文件

    Add.cpp如下:

    #include "add.h"
    
    int add(int a,int b)
    {
        return  a+b;
    }
    
    Mult,cpp如下:
    
    #include "mult.h"
    int mult(int a,int  b)
    {
        return  a*b;
    }

    步骤:编译把两个源码文件生成目标文件

    gcc   -c  .\add.cpp .\mult.cpp  -I./

    步骤,生成静态库:3.使用ar -rsv libxxx.a  *.o制作静态库

    ar -rsv    libdemo.a .\add.o .\mult.o

     3.2 静态库的使用

    步骤1:书写可执行程序.main.cpp如下

    #include <mult.h>
    #include <add.h>
    
    int main()
    
    {
        int a=2,b=3;
        cout<<mult(2,3)<<endl;
        cout<<add(2,3)<<endl;
        return 0;
    }

    步骤2:链接静态库:g++ -o main  .\main.cpp   -L./ -ldemo

    步骤3:验证:如下

    4.动态库生成和使用

    4.1动态库的生成

    步骤1和步骤2,和静态库一样,生成.o文件:

    步骤3:生成动态库

    g++  -shared  -fPIC  -o   libdemo.so  add.cpp   mult.cpp 

     4.2 动态库的使用

    4.2.1 动态链接

    这个是经常遇见的,步骤1和静态库的使用步骤1相同

    步骤2:生成可执行文件

    g++  -o main   .\mult.cpp   -L.  -ldemo

    4.2.2 动态加载

    涉及到函数:

    函数原型

    说明

    const char *dlerror(void)

    当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

    void *dlopen(const char *filename, int flag)

    用于打开指定名字(filename)的动态链接库,并返回操作句柄。调用失败时,将返回NULL值,否则返回的是操作句柄。

    void *dlsym(void *handle, char *symbol)

    根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。由此地址,可以带参数执行相应的函数。

    int dlclose (void *handle)

    用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。2.2在程序中使用动态链接库函数。

    解析:

    函数1:dlsym(void *handle, char *symbol)

    filename:如果名字不以“/”开头,则非绝对路径名,将按下列先后顺序查找该文件。

    (1)用户环境变量中的LD_LIBRARY_PATH的值;

    (2)动态链接缓冲文件/etc/ld.so.cache

    (3)目录/lib,/usr/lib

    flag表示在什么时候解决未定义的符号(调用)。取值有两个:

    1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。

    2) RTLD_NOW :表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。

    函数2:dlsym(void *handle, char *symbol)

    dlsym()的用法一般如下:

    void(add)(int x,int y); 说明一下要调用的动态函数add

    add=dlsym("xxx.so","add"); 打开xxx.so共享库,取add函数地址

    add(89,369); 两个参数89和369调用add函数

    步骤1:程序使用demo.cpp:

    #include "add.h"
    #include <stdio.h>
    #include <dlfcn.h>
    #include <cstdlib>
    extern "C"
    {
        typedef  int (*fn)(int a,int b);
    }
    
    
    int main(int argc, char const *argv[])
    {
    	void *handle = dlopen("libdemo.so",RTLD_LAZY);
    	const char *err = dlerror();
    	if(err !=NULL){
    		perror("could not open shared object!");
    	}
    	if (NULL != handle) {
    		printf("open sussess\n");
    
    	}
    
    	fn  add_func = (fn)dlsym(handle,"add");
    	cout<<add_func (23,34)<<endl;
    	
    	dlclose(handle);
    	return 0;
    }

    步骤2:编译

    g++  -g   -o  demo   demo.cpp   -L./   -ldemo  -ldl

    步骤3:验证

    ./demo

    如下:

     

    5.工具使用

    5.1 nm工具

    nm可以查看库中有那些函数:列出.o .a .so中的符号信息,包括诸如符号的值,符号类型及符号名称等。所谓符号,通常指定义出的函数,全局变量等等。

    https://www.cnblogs.com/itech/archive/2012/09/16/2687423.html

    5.2 ldd命令

    可以查看可执行文件或者库连接那些文件,及其连接是否正确

    参考:

    Linux中的静态库与动态库 - 独孤剑—宇枫 - 博客园

    静态库和动态库的区别 - 阿玛尼迪迪 - 博客园

    展开全文
  • Ndk之C/C++静态库生成及使用 for Android sutio 3.x重要说明 本文是参照上面的资料得来的。感谢大神的资料。涉及到的参考资料如下:静态库和动态库的编译lib module工程结构如下imagelib module 编译环境配置静态库的...

    Ndk之C/C++静态库生成及使用 for Android sutio 3.x

    重要说明 本文是参照上面的资料得来的。感谢大神的资料。

    涉及到的参考资料如下:

    静态库和动态库的编译

    lib module工程结构如下

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    lib module 编译环境配置

    静态库的编译

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    动态库的编译

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    lib CMakeLists.txt

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    build.gradle配置

    android {

    defaultConfig {

    externalNativeBuild {

    cmake {

    arguments '-DANDROID_PLATFORM=android-13',

    '-DANDROID_TOOLCHAIN=clang'

    abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64', 'x86'

    targets 'nannan', 'haohao'

    }

    }

    }

    externalNativeBuild {

    cmake {

    path "CMakeLists.txt"

    }

    }

    }

    make module 或 进入模块目录,执行 gradle clean build 即生成.a和.so 到指定目录

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    第三方静态库和动态库的使用

    环境配置

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    第三方库的.h头文件需要复制到include目录下

    动态库和静态库的调用

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    当前工程的CMakeLists.txt配置

    e9ae5d0e8427?utm_campaign=haruki&utm_content=note&utm_medium=reader_share&utm_source=qq

    image

    当前工程的 build.gradle配置

    android {

    defaultConfig {

    externalNativeBuild {

    cmake {

    arguments '-DANDROID_PLATFORM=android-15',

    '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'

    abiFilters 'armeabi-v7a','x86_64', 'arm64-v8a','x86'

    }

    }

    }

    buildTypes {

    release {

    minifyEnabled false

    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

    }

    }

    externalNativeBuild {

    cmake {

    path "CMakeLists.txt"

    }

    }

    /*解决More than one file was found with OS independent path 'lib/x86/libnative.so'*/

    packagingOptions {

    pickFirst 'lib/armeabi-v7a/libnative.so'

    pickFirst 'lib/x86_64/libnative.so'

    pickFirst 'lib/x86/libnative.so'

    pickFirst 'lib/arm64-v8a/libnative.so'

    }

    }

    packagingOptions这里面可是重点哦。More than one file was found with OS independent path 'lib/x86/libnative.so这个破玩意儿,整了一下午才解决。是看到了这个兄弟的博客才解决的,感谢一下!

    再次声明,由于本篇文章的由来,是基于大神的博客,是看了大神的github的源码工程得来的,不敢居功,相同的内容不列出,只大概的介绍一下重点部分。需要详细了解的。查看大神的博客。

    展开全文
  • 关注+星标公众号,不错过精彩内容作者| strongerHuang微信公众号 | strongerHuang,对于程序员的人来说都知道。但有很多初学者,以及工作几年的读者对的理解还处...

    关注+星标公众,不错过精彩内容

    0ec1902c442a78d3ef6dc9b1b2eb6b8c.png

    作者 | strongerHuang

    微信公众号 | strongerHuang

    库,对于程序员的人来说都知道。但有很多初学者,以及工作几年的读者对库的理解还处于书本概念阶段。

    今天就来结合分享一下:Keil、IAR静态库生成和使用的方法,以及静态与动态库的区别

    关于库

    库函数是把函数源代码经过编译后放到库里,供别人使用的一种方式。

    比如:将一些常用,或者不想让别人看到源代码的函数(.c文件),一起编译生成一个(.lib)库文件。

    调用的时候,需要将(.lib)库函数包含在当前工程,同时需要在头文件(.h文件)中声明函数,然后通过#include直接调用对应的函数即可。

    1.微库(MicroLib)

    很多读者都知道printf打印函数,比如:

    printf("微信公众号:strongerHuang\n");

    我们在代码中调用printf函数打印数据时,就是调用了标准的“微库”,比如Keil、IAR中使用“微库”,需要配置:

    Keil MDK使用微库

    Project -> Options for Target -> Target 勾选上“Use Micro LIB”,如下图:

    72cb6515a252b613de10257f1f170914.png

    同时,如果通过串口打印输出,就需要底层“串口重定义”:

    int fputc(int ch, FILE *f)
    {
      USART1_SendByte((uint8_t)ch); //对应底层串口输出函数
    
    
      return ch;
    }

    IAR EWARM使用微库

    Project -> Options -> General Options -> Library Configuration 选中“Full”,如下图:

    a950f525b6f2c0d1be838d26cd1d933d.png

    2.什么情况下要生成库?

    a.代码模块化定型。也就是说模块代码的功能在经过无数次验证,并无误后,方便团队的协同开发,这个时候可以将模块代码生成库。

    b.提供SDK给客户开发。这里一般是指源代码对客户不具有公开性的原因,包括某些特有算法、实现特有功能的具体过程等。

    生成库的原则?

    简单来说就是使代码结构化、模块化、源码不具公开性等。要求代码高内聚、低耦合。

    Keil、IAR如何生成库?

    代码工程生成库的过程只需要对工程进行配置即可,这里再简单讲一下过程,其实在我KeilIAR系列教程中有相关内容的详细描述。

    1.Keil MDK

    Project -> Options for Target -> Output 勾选上“Create Library”即可。

    14e84b9f5b26132b041a003fe5164c3a.png

    注:Keil 生成的库文件是以“.Lib”为后缀的文件

    2.IAR EWARM

    Project -> Options -> General Options -> Output 勾选上“Library”即可。

    c776fb55f09a2325fd56a0a661848235.png

    注:IAR 生成的库文件是以“.a”为后缀的文件

    库在工程的使用方法

    “.Lib”、“.a”这种库大家可以理解为经过处理的“.c”源文件,只是我们看不到源文件。我们只需要像添加“.c”文件,将其添加到工程即可。

    如下图,我们将STM32F10x_StdPeriph_Driver标准外设库生成“STM32F10x_StdPeriph_Driver.a”库,添加到工程中:

    66eb874c0830d5dd2f8e8660c38a5b45.png

    静态库和动态库的区别?

    上面Keil生成的库是以“.Lib”为后缀的文件,IAR是以“.a”为后缀的文件,你们知道他们是静态库还是动态库吗?

    答案是:二者都是静态库。

    为什么都是静态库呢?先看一下静态库和动态库的区别就会知道。

    简单的来说二者的区别:

    • 静态库:就是在编译的时候直接将需要的代码连接进可执行程序中去;

    • 动态库:就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。

    从上面的描述可以知道,静态库是我们MCU开发者常用的一种,而动态库常用于Linux、Windows等开发场合。

    ------------ END ------------

    e029404a9963ffb26cb2a43c8b695938.png

    C语言:一个非常完美MAX宏的诞生及5次进化

    2e862c2c390375901fad3d352dcab47a.png

    很棒的C语言入门笔记,推荐收藏!

    c703f3d272409c766b371ecb4ed59a6c.png

    干货 | 一文讲透STM32串口DMA收发机制

    2e2a2a7eb4e8c706a978238ae9218e87.png

    晓宇姐姐带你软硬结合,感受下ADC DMA采集多路电压电流的最佳姿势

    点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

    展开全文
  • 静态库的打包及使用3.1 链接的本质3.2 静态库打包3.3 静态库使用4. 动态库的打包及使用4.1 动态库打包4.2 动态库的使用 1. 动静态库的概念 静态库(.a):程序在 编译链接 的时候把库的代码链接到可执行文件中。...

    1. 动静态库的概念

    静态库(.a):程序在 编译链接 的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
    动态库(.so):程序在 运行 的时候才去链接动态库的代码,多个程序共享使用库的代码。

    我们都知道一个操作系统本身就会自带许多动静态库文件,一般系统自带的动静态库都会放在指定目录下,编译器在链接时会直接去指定位置找到对应的库文件。

    一开始我想通过链接系统库,从而向大家介绍动静态链接的一些基本原理。

    2. 动静态链接原理

    mytest.c是我在当前目录下创建的一个源文件:

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

    在Linux系统下,文件生成可执行程序时默认链接的是动态库,如果要链接静态库则需要加上-static选项。

    接着通过下面命令分别来生成动态链接和静态链接的可执行程序:

    gcc -o mytest mytest.c
    gcc -o mytest_static mytest.c -static

    在这里插入图片描述
    大家看到这里我分别生成了两个可执行程序,动态链接mytest和静态链接mytest_static。观察这两个可执行程序的详细信息,最直观的一个差别就是 静态程序的大小竟然是动态程序的100倍!

    下面我来为大家分析动静态链接的原理。

    2.1动态链接原理

    在这里插入图片描述
    动态链接时代码默认从上到下执行,执行到printf函数时,源代码中并没有printf函数的执行逻辑。接下来编译器会跳转到动态库里执行printf函数,执行完之后把结果(打印"hello world")带回来,然后继续执行下面的代码。

    动态库的优点是:他不会把库里面的代码拷贝进来,所以实际生成的可执行程序体积比较小。

    2.2 静态链接原理

    在这里插入图片描述
    静态链接时代码还是从上往下执行,但是当执行到printf函数时静态链接采取的做法是,直接将库里面的printf代码拷贝到程序里,再顺次往下执行。

    静态库的优点:将对应的代码拷贝进可执行程序,程序的可移植性强
    静态库的缺点:体积较大(从上面的图可以看出,仅仅一条打印语句,静态库的大小就是动态库的100倍,更别提代码多起来了)

    2.3 总结

    • 动态库是我们需要时才调用它,所以动态库是运行时才加载来,并且整个系统中可以只有一份动态库(共享)
    • 静态库是在编译链接时加载进来的,每个程序各自私有一份,可能会比较占资源(比如两个程序都用了printf函数,那么printf函数的代码就会被拷贝两份)

    理解完系统库的链接原理之后,下面我来教大家如何打包生成我们自己的动静态库。

    3. 静态库的打包及使用

    3.1 链接的本质

    首先我们要知道,一个第三方库必须要包含两个东西:
    1.一批头文件(告诉用户,有什么方法可以使用,接口参数是什么意思)
    2.一个或多个库文件头文件具体的实现方法,供用户来进行动静态链接(以二进制的形式告诉用户代码是怎么生成的)

    前面我们一直再谈动态链接,静态链接,大家有没有思考过链接的本质是什么?

    回想将一段代码翻译成可执行程序的过程,这中间要经过四步:预处理、编译、汇编、链接

    • 预处理(进行宏替换) 生成.i文件
    • 编译(生成汇编)生成.s文件
    • 汇编(生成机器可识别代码)
    • 生成.o文件 链接(生成可执行文件或库文件)

    所以链接的本质把.o文件链接生成可执行程序!!
    而我们生成动静态库的原理就是把你的代码中所有的.o文件打包起来即可!!

    3.2 静态库打包

    这里我写了四个文件:

    //myadd.h
    #pragma once 
    #include <stdio.h>
    int MyAdd(int x, int y);
    
    //myadd.c
    #include "myadd.h"
    int  MyAdd(int x, int y)
    {
      return x + y;
    }
    
    //mysub.h
    #pragma once 
    #include <stdio.h>
    int MySub(int x, int y);
    
    //mysub.c
    #include"mysub.h"
    int MySub(int x, int y)
    {
      return x - y;
    }
    

    两种方法分别实现加法运算与减法运算,已经声明这两个方法的源文件。

    现在我想实现一个静态库,这个库可以为外界提供两个接口,一个实现加法运算,一个实现减法运算。

    第一步我们要先来生成这两个源文件的.o文件:
    在这里插入图片描述
    接下来我们要做的就是将这两个.o文件打包生成静态库。

    Makefile编写如下:
    在这里插入图片描述

    打包生成静态库的命令是:

    ar -rc libmymath.a myadd.o mysub.o

    • ar是打包静态库的命令
    • rc是一个选项,代表replace和create,含义是,如果要生成的这个库存在,那就直接替换它,如果不存在,那就生成一个。

    这样一个静态库就打包出来了:
    在这里插入图片描述
    这里我再来大家介绍一下库的命名规则lib + 库名 + 后缀

    也就是所我们这里所生成的静态库的库名叫mymath,后缀是.a(一般默认动态库以.so为后缀,静态库以.a为后缀)

    接下来我再来教大家如何去链接我们所生成的静态库:

    3.3 静态库使用

    静态库打包成功后,接下来就要交给用户去使用了,我们需要做的是将库文件和头文件(静态库的使用说明书)交付给别人。

    这里我们将头文件和库文件放到同一个目录下,然后传给别人:
    在这里插入图片描述
    大家看到,我将头文件和库文件分别放在了mylib目录下的include和lib的子目录里,接下来我便将这个文件拷贝给mytest.c源文件去进行静态链接。

    mytest.c的代码:

    #include <stdio.h>
    #include "myadd.h"
    
    int main()
    {
      int x = 10;
      int y = 20;
      printf("add is %d\n", MyAdd(x, y)); 
      printf("hello world\n");
      return 0;
    }
    

    我在mytest.c文件中调用了mylib库里面的MyAdd函数,编译命令如下:

    gcc -o mytest_static mytest.c -I./mylib/include -L./mylib/lib -l mymath -static

    大家看到,这次在链接我们刚刚打包的静态库时,出了-static还需要加上三个选项-I、-L、-l.

    • -I选项,I是include的首字母,该选项的含义是指定一个路径,也就是告诉编译器,你在找头文件的时候先去默认路径下去找,找不到,再去我的指定路径下去找。
    • -L选项,L是lib的首字母,表示自定义库的搜索路径。
    • -l选项指定库名,注意这里的库名指的是静态库的名称,而不是库的文件名,两者的区别上面我有提到过的。

    可能有人会疑惑,前面在链接系统库时,为什么不用加这么多选项,而我们自己的库却需要?

    原因实际上我已经提到过了, 系统库是放在操作系统的指定路径下的,所以链接时编译器会默认去该路径下查找,不存在找不到的情况。但是对于一个第三方库,编译器并不知道所链接的位置,因此我们需要指定库的头文件,库文件,以及库名去供编译器精确链接。

    执行结果:
    在这里插入图片描述
    大家看到mytest.c文件,成功链接我们刚刚打包生成的静态库,静态可执行程序mytest_static,并且成功执行mymath库的函数功能。

    学完静态库的打包及使用,下面我们再来看动态库:

    4. 动态库的打包及使用

    4.1 动态库打包

    还是上面的四个文件,这次我们来打包生成一个动态库:

    //myadd.h
    #pragma once 
    #include <stdio.h>
    int MyAdd(int x, int y);
    
    //myadd.c
    #include "myadd.h"
    int  MyAdd(int x, int y)
    {
      return x + y;
    }
    
    //mysub.h
    #pragma once 
    #include <stdio.h>
    int MySub(int x, int y);
    
    //mysub.c
    #include"mysub.h"
    int MySub(int x, int y)
    {
      return x - y;
    }
    

    Makefile编写如下:
    在这里插入图片描述
    大家看到生成动态库时需要加-shared选项,生成.o文件需要加了-fPIC选项,下面来解释:

    • shared: 表示生成共享库格式
    • fPIC:产生位置无关码
    • $<:匹配依赖关系中的所有源文件。

    再出来make执行就可以生成我们想要的动态库了:
    在这里插入图片描述

    4.2 动态库的使用

    动态库生成好之后,接下来我们要做的和静态库一样,就是把库文件和头文件放在同一个目录下交给用户。

    我依旧是把该目录拷贝到mytest.c源文件所在的路径下,我们来看源文件mytest.c代码:

    #include <stdio.h>
    #include "myadd.h"
    
    int main()
    {
      int x = 10;
      int y = 20;
      printf("add is %d\n", MyAdd(x, y)); 
      printf("sub is %d\n", MySub(x, y));
      printf("hello world\n");
      return 0;
    }
    

    下面我们来链接这个动态库,一开始我用的指令和链接静态库指令一样,只是去掉了-static选项:

    gcc -o mytest_static mytest.c -I./mylib/include -L./mylib/lib -l mymath

    我们来看执行结果:
    在这里插入图片描述
    我们看到make之后成功生成了一个可执行程序mytest,但是我在执行这个mytest程序时确保错了,提示找不到这个共享库。这是什么原因,我明明已经告诉你库的搜索路径和库名了啊,你怎么还是找不到。

    这里我们就要从动态链接的根本去考虑了,上面我说过, 动态库是程序运行之后才把库加载到内存中的,这个加载由谁来完成?当然是操作系统。而你这个告诉的路径是给谁告诉的?仅仅是告诉了编译器。因此,我们这里还需要告诉操作系统库的路径!

    这里我们就需要了解一个环境变量 LD_LIBRARY_PATH该环境变量里面保存的是系统默认找动态库的搜索路径这里我们用export命令将当前库绝对路径导入该环境变量中:
    在这里插入图片描述
    导入之后我们看到程序可以成功进行动态链接,然后求出对应结果。


    本篇文章到这里就全部结束了,我想有的朋友点进来可能只是想快速了解一下使用方法,但是我讲的好像有些繁琐了。当然我还是更想通过一篇文章去让大家了解一些动静态库的底层原理,多接触接触底层对自身学习体系的养成还是很有帮助的。

    最后希望这篇文章可以为大家带来帮助,文章里有什么不懂,或者有需要改进的地方欢迎大家私信来问我。

    展开全文
  • Linux静态库生成指南

    2021-05-17 10:58:09
    在Linux上创建静态库的步骤如下:写源文件,通过c 生成目标文件。用r 归档目标文件,生成静态库。配合静态库,写一个使用静态库中函数的头文件。使用静态库时,在源码中包含对应的头文件,链接时记得链接自己的库。...
  • 静态库生成 新建一个静态库的项目,如图1.1所示:项目名称为test 1. 选择项目类型 选择项目类型为静态链接库,设定项目路径。共享库是创建动态链接库,后缀名为.so,vs上为.dll。 3. 选择下一步,...
  • GCC gcc 与 g++ 分别是 gnu 的 c 和c++ 编译器 gcc/g++ 在执行编译工作的时候,总共需要4步 预处理,生成 .i 的文件[预处理器cpp] ...**直接生成可执行文件:**不带options,编译链接并生成可执行文件,
  • 静态库 先基于.cpp或者.c文件生成对应的.o文件,将几个.o文件 使用ar -cr命令 生成libname.a文件 libname.a 为静态库, name 为静态库的名字 1.静态库的两个函数对应四个文件,一个函数对应一个.h声明文件和.cpp实现...
  • 1.生成动态。1)先写configure.in,用autoscan命令生成configure.scan,然后将其重命名为configure.in,并修改其中内容如下:#-*- Autoconf -*-# Process this file with autoconf to produce a configurescript.AC_...
  • } 在CMakeLists.txt中加入calcul.cpp image.png 在native-lib.cpp中调用add方法 image.png 在MainActivity中调用 image.png 以上是c代码例子编写 , 下面生成.a静态库供别人使用 打开CMakeLists.txt文件,将add_...
  • 静态库生成动态库,再对动态库隐式调用 以项目lib7zMT为例 1.首先将原本静态库的配置属性改为如下图1所示,重新生成就可以找到动态库和它的导入库,如图2 图1 图2 2.调用上一步生成的导入库lib7zMT.lib,如图3所...
  • #生成静态库,需以lib开头 ar crv libdemo.a demo.o #链接并使用静态库 -L 指定lib位置 -l库的名称 g++ -o main main.cpp -L ./lib -ldemo 动态库: libxxx.so #动态库需要编译的时候指定 -fPIC g++ -c -fPIC add....
  • 动态生成:1、/*mysum.c*/#include #include "src.h"int sum(int a,int b){return (a+b);}2、/*mysum.h*/#ifndef __SRC_H__#define __SRC_H__int sum(int a,int b);#endif3、/*main.c*/#include extern int sum...
  • 静态库生成 先定义一个简单的 减法函数 sub2() 并且在 main2中调用它 尝试输出执行结果 发生错误 未在main2中声明 sub2函数 在main2.c中加上声明 或者 生成sub.h 并在main2.c中 引入头文件 #include"sub.h" 已...
  • 工程实践中,经常遇到动态库、静态库的创建和使用,使用cmake可以方便地完成跨平台编译。 此例,写了一个用于实现加法和减法的类,并将其编译成动态库和静态库,并由可执行文件来调用它们。 静态库:SolutionDLL ...
  • 生成静态库 在linux环境下输入ar cr libmyTest.a Test.o, 查看当前目录下是否生成了库文件libmyTest.a文件,其中ar为linux环境下的创建、修改库文件的指令, cr为该指令的选项命令. 4. 测试 输入gcc -o main main...
  • 使用 CMake 生成动态库/静态库 文章目录使用 CMake 生成动态库/静态库先看例子简单解释一下一些目前能想到的点对外提供动态库 先看例子 废话不多说,上 CMakeLists.txt cmake_minimum_required(VERSION 3.16) ...
  • vs在生成动态库时会一并生成pdb文件用于调试,但是在生成静态库是往往只有一个lib文件,此时如果不指定相关编译选项,那么生成静态库将无法用于问题排查。我们可以告知vs在生成静态库是一并将pdb信息融入lib文件。...
  • 一、用gcc生成静态库和动态库 hello实例 ①创建hello.c文件 ②预处理生成hello.i文件 ③打开hello.i文件,代码如下 ④将预处理的hello.i文件汇编生成汇编程序hello.s
  • 1、静态库生成 (1)项目-右键属性-常规-配置类型-选静态库; (2)点击生成,Debug文件夹下出现lib静态库; 2、静态库使用 (1)新建一个测试项目,将生成的funAdd.h和funAdd.lib复制到新工程目录下; ...
  • cmake:add_library生成静态库和动态库

    千次阅读 2020-12-26 00:29:55
    有时我们只需要编译出动态库,静态库,然后等着让其它程序去使用。让我们看下这种情况该如何使用cmake 实践 编写代码 项目结构如下: /* ** testFunc.c */ #include <stdio.h> #include "testFunc.h" void ...
  • 静态库的创建 生成静态库,需要先对源文件进行汇编操作 (使用参数 -c) 得到二进制格式的目标文件 (.o 格式), 然后在通过 ar 工具将目标文件打包就可以得到静态库文件了 (libxxx.a)。 生成静态链接库的具体步骤如下: ...
  • 但与直接link目标文件不同的是,ld以默认参数执行时,并把静态库中没有用到的函数过滤掉,导致生成的so并未包含所要的函数,因此要加上--whole-archive参数,以保证所有的函数都包含在生成的so中。在使用cmake时,...
  • 当前环境:win10 1、File—> New Project ... 静态库的话选择static, 点击创建 点击create之后生成的项目如下 点击菜单上的“Build->Build Project”,可以看到生成了liblibhelloworld.dll ...
  • 发现Crash的目标模块是A.dll它是我们自己的代码,但是Crash的第三方是通过静态链接到它里面的。也就是说Crash的实际代码是第三 方写的,没有源码,但是VS竟然能显示出行号!反汇编竟然能显示出文...
  • gcc分别链接静态库和动态库生成可执行文件gcc分别链接静态库和动态库生成可执行文件本文分别通过链接静态库和动态库来编译可执行文件,在使用gcc编译的过程中了解链接静态库和动态库的区别与联系,同时深入理解Linux...
  • 本文基于GCC编译器,试验其生成静态库及动态库的过程,内含两个代码实例,最后通过测试汇编代码,gcc逐步编译。
  • } 先用以下的命令来生成test.o, a.sa, b.sa文件: gcc a.c -c -o a.o ar -q a.o a.sa gcc b.c -c -o b.o ar -q b.o b.sa gcc test.c -c -o test.o gcc -shared -Wl,--no-whole-archive a.sa b.sa -Wl,--no-whole-...
  • QT中静态库生成与使用一. 静态库生成1. 测试目录: lib2. 源码文件名: mywindow.h, mywindow.cpp, 类MyWindow继承于QPushButton, 并将文字设置为"I'm in class MyWindow";3. 编写项目文件: mywindow.pro注意两点:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 363,490
精华内容 145,396
关键字:

静态库生成