C语言-模块化-Clion(静态库,动态库)使用

x33g5p2x  于2022-07-10 转载在 其他  
字(3.8k)|赞(0)|评价(0)|浏览(810)

什么是模块化编程

模块化编程就是我们一个复杂的项目分成很多模块,比如一个单片机项目,就可能分为:主函数模块,液晶显示和数码管显示模块,时间延时模块,温度传感器模块等。而一个程序工程包含多个源文件(.c 文件和 .h 文件),每个 .c 文件可以被称为一个模块,每一个模块都有其各自的功能,而每一个.h文件则是声明该模块,相当于功能说明书 模块化编程在嵌入式中是必须要掌握的技能。

模块化编程的好处

开发C程序时,当代码量较大功能较复杂时,单一文件程序会使得文件非常巨大,代码量非常大,成千上万行的代码在一个文件中不便于修改和维护,因此需要将不同的功能模块放在不同的文件中。

并且在团队合作开发的时候,需要模块化开发。每个人负责一部分功能的开发,而你所负责的模块,你需要将你负责的模块功能写好,封装好,之后形成一个.c与.h ,然后交付给项目组长,组长则负责整体框架(main)的编写与各个模块的组合调试,最后各个模块的组合,形成了整个工程。由此可见,模块化可以有效的提高团队开发的分工协作效率。对于整个项目开发有着很大的好处

模块化开发过程如下

  1. 创建.c文件
  2. 在.c文件内定义需要的函数和变量
  3. 创建.h文件,文件名要与.c文件一致
  4. 在.h文件中声明需要让调用方知道的函数和变量
  5. 在调用方文件中包含.h文件,直接调用.h文件中声明的内容即可

注意事项:

  • .h头文件格式一定要按照下面这格式进行
#ifndef DEMO1_CALCULATE_H  // 避免多个文件重复导入
#define DEMO1_CALCULATE_H  // 定义一个预处理宏定义

//extern   声明代码

#endif //DEMO1_CALCULATE_H   表示条件命令的结束
  • 导入.h文件的时候不能使用<> 而是使用" " 因为<>方式只会到系统的专门目录找,而这里没有我们定义的模块 ,而" "方式编译器会先到当前的工程项目所在目录下找,找不到再到系统专门目录下找
  • 定义的x.c和x.h要在同一个目录下不然引入x.h的时候找不到.c源码
  • .h文件 不能定义具体实现 ,只能进行声明, 而具体实现都需要在.c文件中定义
  • 函数声明时,extern可有可无,但是变量的声明必须要有,否则编译时不能识别。. (建议都写上)
  • 不想让外界知道的信息,就不应该出现在.h头文件里,而想让外部调用的函数或变量,则一定要在头文件中声明
  • 头文件(.h)命名应与源文件(.c)一致,便于清晰的查看各个头文件
  • 模块内不想被外部引用的函数和全局变量需在.c文件头以static关键字声明, 这样这些函数和变量只会在当前.c文件中起到作用,一来可以避免函数名的重复;二来可以保护内部的实现数据,防止被破坏 ,比如: static void lEDOpen();
  • 模块中想要被其他文件访问的变量,一定要是全局变量,并且在.h中声明
  • 要尽量减少全局变量的使用,因为全局变量的生命周期是从程序的开始到程序的结束的,这意味着你在其他源文件中调用这个变量时,可能会产生同名变量以及变量数值错误等问题, 这个是非常不好把控的,程序一旦庞大起来,这就是灾难

模块化演示

然后我们在需要调用的地方,将头文件导进来就行了,之后就能使用头文件中声明的内容了

在上面的案例中我们只是在main.c文件中应用了模块,那么模块和模块之间能相互引用吗? 答案是可以的,直接导入就行了

代码库

代码编译过程

静态库

静态库,顾名思义,它是静态的,也就是说它不会被动态编译,它只会静态编译,节省了编译时间,提高了编译速度。同一份静态库,可以被多个程序进行编译,也就实现了代码的复用共享。

静态库的后缀一般有2种.a(linux) , .lib(windows) ,但是在windows下MinGW编译的静态库也是.a的所以如果使用MinGw进行编译代码的话.a文件能通用的

静态库命名规则: 这类库的名字一般是libxxx.a;或者 libxxx.lib; 而xxx是库的名称

动态库

动态库,就是程序应用启动的时候,动态加载的,因为它一般是在系统运行的时候就已经运行的动态库,因此其它应用可以直接使用它,并且同一个动态库可以被多个应用共享使用,在系统中对于一个动态库只会存在一份,这大大节省了内存空间,大大提升了系统的性能。

动态库的后缀一般也是2种 展名分别为:.so( linux )或者 .dll(windows)

动态库命名规则: 这类库的名字一般是libxxx.so 或者libxxx.dll 而xxx是库的名称

Clion库的使用

CMakeLists.txt文件使用

C语言-Cmake-CMakeLists.txt教程 可以参考这篇文章

静态库

创建静态库

先写好c代码,在demo中调试没问题了,那么我们就可以将相关的代码copy到静态库中进行打包了,下面就创建一个静态库

然后随便创建几个.c和.h文件 如下:

然后可以参考C语言-Cmake-CMakeLists.txt教程 ->打包静态或动态库CMakeLists.txt(通用) 这篇文章进行配置CMakeLists.txt ,之后打包效果如下:

注意: 打包后会自动在项目名称前加lib ,所以在创建的时候无效前缀加lib

使用静态库

然后我们将打包好的libtool.a 和头文件目录tool 都拷贝到需要的地方,然后可以参考C语言-Cmake-CMakeLists.txt教程-> 项目编译CMakeLists.txt(静态动态库通用)这篇文章, 进行配置CMakeLists.txt, 项目编译之后在调用的地方使用#include "头文件"就行

如果发现编译错误那么,记得刷新Clion-CMake的缓存

动态库

创建动态库

先写好c代码,在demo中调试没问题了,那么我们就可以将相关的代码copy到动态库中进行打包了,下面就创建一个动态库

然后随便创建几个.c和.h文件 如下:

然后可以参考C语言-Cmake-CMakeLists.txt教程 ->打包静态或动态库CMakeLists.txt(通用) 这篇文章进行配置CMakeLists.txt ,之后打包效果如下:

使用动态库

使用MinGW动态打包后就会出现两个文件.dll.dll.a 我们只需要.dll 就行,然后我们将打包好的libtool1.dll 和头文件目录tool1 都拷贝到需要的地方,然后可以参考C语言-Cmake-CMakeLists.txt教程-> 项目编译CMakeLists.txt(静态动态库通用)这篇文章, 进行配置CMakeLists.txt, 项目编译之后在调用的地方使用#include "头文件"就行

上面可以看出来运行报错了,这是因为默认exe程序会去当前目录下找dll文件如果没有找到那么就会去环境变量里找,都没有找到那么就报错了具体解决办法,可以参考这篇文章C语言-Cmake-CMakeLists.txt教程动态库导入无效,报错问题

静态库和动态库混合使用

可以参考这篇文章C语言-Cmake-CMakeLists.txt教程打包静态或动态库CMakeLists.txt(通用)

查看动态库或者静态库

查看动态库定义的函数或变量 readelf -c xxx.a

查看动态库定义的函数或变量 readelf -A xxx.so

查看库里所有文件列表: ar -t xxx.a

查找静态库里指定的函数或变量 nm -o xxx.a | grep "yyy"

查找动态库里指定的函数或变量 nm -o xxx.so | grep "yyy"

nm 常见的符号类型:

A 该符号的值在今后的链接中将不再改变;
B 该符号放在BSS段中,通常是那些未初始化的全局变量;
D 该符号放在普通的数据段中,通常是那些已经初始化的全局变量;
T 该符号放在代码段中,通常是那些全局非静态函数;
U 该符号未定义过,需要自其他对象文件中链接进来;
W 未明确指定的弱链接符号;同链接的其他对象文件中有它的定义就用上,否则就用一个系统特别指定的默认值。

小技巧

常用的工具类我们可以使用静态库, 频繁升级的部分我们可以使用动态库

  • 静态库的好处就是打包后的exe不需要依赖任何文件就能运行,只是exe文件会比较大
  • 动态库的好处就是打包后的exe文件小,升级只需替换对应的dll文件就行,坏处就是dll找不到或者丢失程序就没法运行了

注意: 动态库代码和项目代码是分离的,如果更新的版本与原来的版本不兼容的话,使用动态库的新版本加载后有可能会出问题导致项目崩溃等情况。

主要还是看项目升级频繁吗?

  • 如果只是单存的开发一个自己使用的工具或者以后不打算升级了,那么使用静态库是非常不错的选择, 因为移植性强,在哪里都能直接用无须安装和配置,双击就运行了
  • 如果是商用项目经常需要升级扩展,那么不用想动态库就是不二的选择,升级和扩展只需要添加或者更换部分的dll就行
  • 当然很多时候我们静态和动态可以混合使用, 静态库主要用于工具文件或者项目核心功能, 动态库用于项目的变化频繁的功能, (静态库和动态库都有相同的文件,内部方法也相同那么优先静态库)

点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复感谢,配合,希望我的努力对你有帮助^_^

免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我。

相关文章