使用C语言来实现模块化
除了C语言以及C++编程语言之外,在其它现在非常流行的开发语言中,比如说:java,php,jsp等等。我们很难想象到缺少标准化的模块管理机制是一件多么可怕的事情。但是这往往也是由C语言本身的设计哲学决定出来的:将尽可能多的可能性留给开发人员。然后根据实际情况的系统,根据大家的实际需要来定制一些自己所需要的东西。
对于一些稍微小一点的系统来说(就是我们在开发过程中通常会接触到的系统),一般情况下我们都会考虑选择轻量一些的源码级方案。假如不是小的系统,相反是一些巨型系统来说(就比如说:类似Windows这样的操作系统),那么一般我们都会考虑使用一种二进制级的模块化方案。由模块它自己来提供元信息,又或者是我们还可以使用统一的管理方案(就比如说:注册表等工具)。

但是我们首先往往要考虑到一个问题,那就是模块的初始化过程以及依赖关系这两个部分。
1、依赖关系
其实依赖关系这一个部分我们可以放由加载器又或者是链接器来进行解决。尤其大家在使用C语言的时候,简单的动态库或者是静态库,通通都不太会给我们引起很大的麻烦,所以大家可以非常的放心。
但是C++编程语言却不是这样了,在C++中有某一些特性(就比如说模板类静态成员的构造)就一定要对早期只供C语言使用的链接器做一些增强。就算是一些很精心去进行编写的C++库,也有可能会出现一些意外的bug(即程序错误)。这些程序错误往往如果想要查询出来的话,往往就需要对链接,加载过程,编译有很深刻的理解,才可以查出来。在这里大家要注意一点哦,那就是小编写这一段话,并不说要根据这样来反对大家使用C++编程语言来进行开发程序。
2、模块的初始化过程
那么我们往往更需要着重管理的,则是模块的初始化过程这一部分。
对于一些打包在一起的一个库(比如说:msvcrt又或者是glibc等),往往都会在加载的时候有一个初始化入口,以及卸载的时候都会有结束的代码。但是小编在这里想说的不是这一个问题,而是大家内部拆分的更小的模块的相互依赖关系。问题就是在于:究竟谁先初始化,谁后初始化呢?
通常使用C++编程语言的朋友,都应该发现他的语言级解决方案中,经常使用到的都是单件模块。要么就是由链接器决定以怎样的一个次序来进行生成初始化代码。但是这经常就会因为实际构造次序不同以及依赖关系,从而导致了程序错误的发生(注意事项:小编在好几本关于C++书籍中都见过,待核实。其实小编自己在好久不写C++也并没有实际的错误例子出现);要么就是使用惰性初始化方案。但是大家也应该知道这个惰性初始化也不是万能钥匙来的,另外还有一些额外的开销了。所以,如果是在多线程环境中就一定要尤其需要注意这一点了。
小编在使用C语言制作初期设计时,往往都采用一种足够简单方便的方法。这种简便的方法就是,用编码的规范来进行规定,每一个模块都一定要存在一个初始化函数,要有一个较为规范的名字。就比如说:foo模块的初始化入口叫做:int foo_init()。
假如说大家使用了特定的模块,那么就一定要调用模块初始化函数。这是一个规定来的哟,所以大家一定要遵循咯。
大家一定要注意一点,那就是:初始化函数是间接调用的,并不是直接调用的。这样的做法,为了要避免发生模块重复初始化的问题。就类似一下这种:mod_using(foo_init);。
mod_using的主要作用就是:负责调用初始化函数,并且还可以保证不重复调用,另外它还可以为我们检查一下循环依赖。
在这里的话,我们还约定了初始化是否成功就在于它的一个返回值。(一般情况下在我们的系统中,如果返回值是1的话,那就代表着失败;相反如果是0的话,那就代表着正确)然后我们再定义了一个宏来制作这个使用。如图所示:

注意事项:就个人而言,小编是特别反对滥用宏的。所以大家也要尽可能的避免使用到宏。在这里小编使用了宏,都是经过了慎重的考虑才决定使用的。为了可以去判断一下自己究竟是否真的漏掉了模块初始化,小编却希望可以有一个代码扫描器帮我去判断(可能小编会使用了一个模块,但是却忘记了将它初始化)。宏可以帮助代码扫描分析器更加容易的实现。除此之外,使用宏的话就更加像是对编程语言做的轻微且必要的扩展。
这样的话,小编的系统中模块模块的实现代码最后,往往都会有一个名为init的函数,在里面仅仅只是简单的调用了USING来进行引用其他的模块。就比如说下面这个示范例子,具体的程序代码如图所示:

由于大部分的需求下是不需要模块卸载的,所以在这篇教程中小编就不再来论证这一点了。如果大家想要去了解的话,可以去查阅相关的书籍。
使用C语言来实现模块化的更多相关文章
- 【C语言探索之旅】 第二部分第一课:模块化编程
内容简介 1.课程大纲 2.第二部分第一课: 模块化编程 3.第二部分第二课预告: 进击的指针,C语言王牌 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C ...
- c语言快速入门2
如果你想快速入门计算机,可以参考我的上一篇帖子,先了解一些必备的软知识,然后再来进行语言的快速入门 计算机入门基础知识 c语言快速入门1 1.1.12 函数的概念 函数的定义:c语言的基本单位,c语言 ...
- JVM 平台上的各种语言的开发指南
JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...
- 【C语言探险】 第四课的第二部分:串
内容简单介绍 1.课程大纲 2.第二部分第四课: 字符串 3.第二部分第五课预告: 预处理 课程大纲 我们的课程分为四大部分,每个部分结束后都会有练习题,并会发布答案.还会带大家用C语言编写三个游戏. ...
- 【C语言探索之旅】 第二部分第十课:练习题和习作
内容简介 1.课程大纲 2.第二部分第十一课: 练习题和习作 3.第三部分第一课预告: 安装SDL 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言 ...
- 【C语言探索之旅】 第三部分第一课:SDL开发游戏之安装SDL
内容简介 1.课程大纲 2.第三部分第一课: SDL开发游戏之安装SDL 3.第三部分第二课预告: SDL开发游戏之创建窗口和画布 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会 ...
- 【C语言探索之旅】 第二部分第九课: 实战"悬挂小人"游戏 答案
内容简介 1.课程大纲 2.第二部分第九课: 实战"悬挂小人"游戏 答案 3.第二部分第十课预告: 安全的文本输入 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题, ...
- 【C语言探索之旅】 第二部分第八课:动态分配
内容简介 1.课程大纲 2.第二部分第八课: 动态分配 3.第二部分第九课预告: 实战“悬挂小人”游戏 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言 ...
- 【C语言探索之旅】 第二部分第七课:文件读写
内容简介 1.课程大纲 2.第二部分第七课: 文件读写 3.第二部分第八课预告: 动态分配 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏 ...
随机推荐
- Codeforces - 440C DFS
搜索苦手,注意正负 #include<bits/stdc++.h> #define rep(i,j,k) for(int i = j; i <=k; i++) using names ...
- SElinux学习记录
1.SELinux:是一种基于域类型模型的强制访问控制安全系统,由NSA编写设计成内核模块包含到内核中,相应的某些安全相关的应用也被打了SE Linux补丁 查看Selinux: ps -Z #查看S ...
- Error: Duplicate key name 'PCS_STATS_IDX' (state=42000,code=1061) ----Hive schematool -initSchema -dbType mysql
schematool -initSchema -dbType mysqlMetastore connection URL: jdbc:mysql://localhost/metastore_db?cr ...
- js学习笔记 -- await/ async
await 暂停async function函数,等待Promise处理完成,若Promise 状态为fulfilled,其回调resolve的参数作为await的值,Promise 状态为rejec ...
- python_文件的打开和关闭
文件对象 = open('文件名','使用方式')rt:读取一个txt文件wt: 只写打开一个txt文件,(如果没有该文件则新建该文件)会覆盖原有内容at:打开一个txt文件,并从文件指针位置追加写内 ...
- HDFS读写文件流程
读取: 写入:https://www.imooc.com/article/70527
- PlayMaker Play Sound 和 Audio Play
这两个 Action 都可以播放声音 *Play Sound:只要把声音拖进去就可以: *Audio Play:要求游戏对象要有Audio Source组件.
- 织梦dede模板中调用会员信息标签的方法
织梦CMS v5.7调用文章所属会员信息标签 打开官方默认模板article_artcile.htm,我们可以提取出如下代码: {dede:memberinfos} 会员头像:<a href=& ...
- VCL
vcl常用配置 不缓存摸一个资源 在vcl_recv中 if (req.url ~ "private") { return (pass); } 动静分离 先定一个多个backend ...
- C#多样式EXECl导出
sing NPOI.HPSF; using NPOI.HSSF.UserModel; using NPOI.HSSF.Util; using System; using System.Collecti ...