模块化编程就是我们一个复杂的项目分成很多模块,比如一个单片机项目,就可能分为:主函数模块,液晶显示和数码管显示模块,时间延时模块,温度传感器模块等。而一个程序工程包含多个源文件(.c 文件和 .h 文件),每个 .c 文件可以被称为一个模块,每一个模块都有其各自的功能,而每一个.h文件则是声明该模块,相当于功能说明书 模块化编程在嵌入式中是必须要掌握的技能。
开发C程序时,当代码量较大功能较复杂时,单一文件程序会使得文件非常巨大,代码量非常大,成千上万行的代码在一个文件中不便于修改和维护,因此需要将不同的功能模块放在不同的文件中。
并且在团队合作开发的时候,需要模块化开发。每个人负责一部分功能的开发,而你所负责的模块,你需要将你负责的模块功能写好,封装好,之后形成一个.c与.h ,然后交付给项目组长,组长则负责整体框架(main)的编写与各个模块的组合调试,最后各个模块的组合,形成了整个工程。由此可见,模块化可以有效的提高团队开发的分工协作效率。对于整个项目开发有着很大的好处
注意事项:
.h
头文件格式一定要按照下面这格式进行#ifndef DEMO1_CALCULATE_H // 避免多个文件重复导入
#define DEMO1_CALCULATE_H // 定义一个预处理宏定义
//extern 声明代码
#endif //DEMO1_CALCULATE_H 表示条件命令的结束
<>
而是使用" "
因为<>
方式只会到系统的专门目录找,而这里没有我们定义的模块 ,而" "
方式编译器会先到当前的工程项目所在目录下找,找不到再到系统专门目录下找x.c和x.h
要在同一个目录下不然引入x.h的时候找不到.c源码.h文件
不能定义具体实现 ,只能进行声明, 而具体实现都需要在.c文件
中定义.h
头文件里,而想让外部调用的函数或变量,则一定要在头文件中声明.c文件头
以static关键字声明, 这样这些函数和变量只会在当前.c文件中起到作用,一来可以避免函数名的重复;二来可以保护内部的实现数据,防止被破坏 ,比如: static void lEDOpen();
然后我们在需要调用的地方,将头文件导进来就行了,之后就能使用头文件中声明的内容了
在上面的案例中我们只是在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是库的名称
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 未明确指定的弱链接符号;同链接的其他对象文件中有它的定义就用上,否则就用一个系统特别指定的默认值。
常用的工具类我们可以使用静态库, 频繁升级的部分我们可以使用动态库
注意: 动态库代码和项目代码是分离的,如果更新的版本与原来的版本不兼容的话,使用动态库的新版本加载后有可能会出问题导致项目崩溃等情况。
主要还是看项目升级频繁吗?
点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复感谢,配合,希望我的努力对你有帮助^_^
免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://huanmin.blog.csdn.net/article/details/125598942
内容来源于网络,如有侵权,请联系作者删除!