proteucc语言模块化编程是怎么工作的?

C模块化编程
本文转载自 Linux内核那些事
来源:xusong.lie
链接:http://mp./s/ZjmJF-VhEcBUzb5iwTGZ8Q
模块化编程 是指程序核心部分定义好功能的接口,而具体的实现留给各个模块去做。举个现实世界的例子:我们可以在电脑的PCI插槽上安装显卡、声卡或者网卡,原因就是这些硬件都按照PCI接口的规范来制造的。
模块化编程也一样,程序核心部分定义好接口,各个模块按照接口的定义去实现功能,然后把各个模块挂载到程序上即可,这个有点像Java的面向接口编程。如下图:
模块化编程的好处就是最大化灵活性,程序的核心部分不用关心功能的具体实现,只需要调用模块提供的接口即可得到相应的结果。因为各个模块的具体实现各不相同,所以得到的结果也是多样化的。
使用C进行模块化编程
用过C语言编程的人都知道C语言是没有接口的,所以怎么使用C语言进行模块化编程呢?使用C语言的结构体和函数指针可以模拟出Java接口的特性,我们只需定义一个由多个函数指针构成的结构体,然后功能模块实现这个结构体里的函数即可。
例如我们定义一个名为Car的结构体,而这个结构体有两个函数指针,分别是run()和stop():
#ifndef__CAR_H
#define__CAR_H
void(*run)();
void(*stop)();
从上面定义可以知道,实现了run()和stop()方法的模块都可以被称为Car(汽车)。现在我们来编写两个模块,分别是Truck和Van。
Truck模块如下(truck.c):
#include&stdlib.h&
#include&stdio.h&
#include"car.h"
static voidrun()
printf("I am Truck, running...n");
static voidstop()
printf("I am Truck, stopped...n");
structCartruck = {
.run= &run,
.stop= &stop,
Van模块如下(van.c):
#include&stdlib.h&
#include&stdio.h&
#include"car.h"
static voidrun()
printf("I am Van, running...n");
static voidstop()
printf("I am Van, stopped...n");
structCarvan = {
.run= &run,
.stop= &stop,
这样我们编写了两个模块,一个是卡车模块(Truck),一个是客车模块(Van)。为了简单起见,我们只是简单的打印一段文字。现在可以说我们的车是变形金刚了,因为可以随时变成卡车或者客车(嘻嘻)。
我们把模块都写好了,但是怎么把模块应用到程序的核心部分呢?这时候我们需要一个注册机制。因为核心部分不知道我们到底编写了什么模块,所以就需要这个注册机制来告诉核心部分。注册机制很简单,只需要一个函数即可(main.c):
#include"car.h"
externstructCar
externstructCar
structCar*
voidregister_module(structCar*module)
intmain(intargc, char*argv[])
register_module(&truck);
car-&run();
car-&stop();
编译运行后我们会得到以下的结果:
如果把 register_module(&truck);改为register_module(&van);会得到以下结果:
从上面的结果可以看到,我们可以注册不同的模块来提供不同的服务,模块化编程就这样实现了。
Are you kidding me?
C的模块化编程的确是这么简单,但是我们可以实现更强大的功能:使用动态链接库来实现模块化。
使用动态链接库进行模块化编程
Linux提供一种叫动态链接库的技术(Windows也有类似的功能),可以通过系统API动态加载.so文件中的函数或者变量。动态链接库的好处是把程序划分成多个独立的部分编译,每个部分的编译互补影响。例如我们有动态链接库A、B、C,如果发现A有bug,我们只需要修改和重新编译A即可,而不用对B和C进行任何的改动。
下面我们使用动态链接库技术来重写上面的程序。
其实要使用动态链接库技术,只需要把模块编译成.so文件,然后核心部分使用操作系统提供的dlopen()和dlsym()接口来载入模块即可。
1. 把模块编译成.so文件
首先我们修改van.c文件,主要是增加一个让核心部分获取模块接口的方法get_module():
#include&stdlib.h&
#include&stdio.h&
#include"car.h"
static voidrun()
printf("I am Van, running...n");
static voidstop()
printf("I am Van, stopped...n");
structCarmodule = {
.run= &run,
.stop= &stop,
sturct Car *get_module()
然后我们需要把库的源文件编译成无约束位代码。无约束位代码是存储在主内存中的机器码,执行的时候与绝对地址无关。
$ gcc -c -Wall -Werror -fpic van.c
现在让我们将对象文件变成共享库。我们将其命名为van.so:
$gcc -shared -o van.so van.o
这样我们就把van.c编译成动态链接库了。我们使用相同的方法把truck.c编译成truck.so。
2. 在核心部分载入动态链接库
使用动态链接库接口来修改核心部分代码,如下:
#include"Car.h"
#include&dlfcn.h&
#include&stdlib.h&
structCar*
structCar*register_module(char*module_name)
structCar*(*get_module)();
handle = dlopen(module_name, RTLD_LAZY);
if(!handle) {
returnNULL;
get_module = dlsym(handle, "get_module");
if(dlerror() != NULL) {
dlclose(handle);
returnNULL;
dlclose(handle);
returnget_module();
intmain(intargc, char*argv[])
structCar*
if((car = register_module("./van.so")) == NULL) {
car-&run();
car-&stop();
使用以下命令编译代码:
$ gcc -rdynamic -o car main.c -ldl
运行程序后得到结果:
修改 register_module("./van.so")为register_module("./truck.so")得到结果:
可以看到我们成功使用动态链接库改写了程序。
由于模块化编程的灵活性和可扩展性非常好,所以很多流行的软件也提供模块化特性,如:Nginx、PHP和Python等。而这些软件使用的方法与本文介绍的大致相同,有兴趣可以查看这些软件的实现。
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点查看:3920|回复:6
听别人说模块化编程很方便修改,很想学习就是弄不明白,求大神帮助。
版规,发帖可获2无忧币
你先学学面向对象编程
然后再看看com相关的东西
模块化编程是指将系统分成诺干个子系统,子系统又分诺干个模块,
每个模块实现特定的功能!模块化编程是一种至顶向下的设计方式!
版规,回帖可获2无忧币
助理工程师
说白了就是com组件
版规,回帖可获2无忧币
模块化编程是为了更好的管理工程、方便以后移植代码、使主函数或主文件(即有main函数的那个文件)变得简单,因为我们读代码时一般都是从主函数开始读的。
那怎么进行模块化呢?
简单的就是一个功能包装成一个函数,要实现什么功能就调用哪个函数实现。
而复杂点的就是,一个功能模块统一放一个C文件中,这个模块相关的函数全部在这个C文件中实现,在主文件(即有main函数的C文件)想要使用这个模块的功能函数,只需要包含它的头文件就可以调用了。那头文件就只是放这个功能模块的函数声明。
这样子做,以后移植就方便多了。如果别的工程需要这个功能模块,只需复制一下它的C文件已经H文件到这个工程目录下,就能使用。
版规,回帖可获2无忧币
5# 说的很透彻
版规,回帖可获2无忧币
说白了就是把代码分散到各个函数中自学C++根本没工作,奉劝各位想入门千万别学c++,还是学java好些,工作多的是,本人感同身受。我看了《C语言程序设计【java吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:657,042贴子:
自学C++根本没工作,奉劝各位收藏
自学C++根本没工作,奉劝各位想入门千万别学c++,还是学java好些,工作多的是,本人感同身受。我看了《C语言程序设计,机械工业大学》 《C语言模块化编程》《C++程序设计,(基础版)》《c++程序设计(进阶版)》《计算机组成原理与算法导论》《C11标准库》《mysql数据库》《QT creator 快速入门》《深入浅出MFC》《LINUX权威指南》还是被现实打败了,所以千万别学C++,入行还是学习JAVA
兄弟连教育&拉勾网强强联合打造JavaEE.战狼班,Java培训后付费非贷款,入学兄弟连java战狼班,拉勾网战略合作,高起点出Java精英.
c++关键是太难了,,没有7,8年的功力不行
两个都会……
咋了?C++吧 被培训生攻陷了?
只能说会cpp和用cpp工作差距很大,楼主发的这些书是大二的水平
学c++适合去做游戏
活捉10楼**狗
java人太多了,一般人找不到工作,,去学c++啊,工作好找
C++竞争研究生?
就自学基础来说,你还少基本书,一本书是
《数据结构》,因为你这个不看的话,&&c++11标准库》那些vector,hash之类的东西,你不会理解多少,不过你能啃完c++标准库,你也挺有毅力啊。然后你那本linux权威指南,要转linux?
如果你真要转linux,linux这么强大的系统,你没理由不用,你再看看《linux系统编程》。然后你再看看《网络编程》,这个是基于c++的,网络可是热点,没理由不看。c++这个东西很强大,但是玩儿起来很危险,你看《c++标准库》的时候,就明显体会到和java不同了,作者告诉你这个函数集的坑点,让你自己掌控,而且反复强调,高效和健壮,不可兼得。底层的东西,stm32这种单片机,都有c++编译器了,但是底层的东西,都不好学,太多了,书你还得看啊。
2017java学习来上市公司博为峰学java,入学即签就业协议,不就业不收费,查看java课程!java好学吗?java课程来博为峰学,java工程师就业年薪十几万!
我同学培训三个月,班上都找到了。个个offer拿到手软。
c++???** 自学?5年都不可能的事情,c++都是秃头
看书有个**毛用啊!有项目么?动手了么?
看这么多? 面试先一道数据结构算法题就GG
扯,我在百度搞c++年薪38万
我的一个学长,c++很厉害,而且他经常黑java说什么laji语言。他大四毕业在腾讯工作。
一个项目都没有,找**工作。
我感觉好像看过你这帖子
自学时间长,效率低,不如找一家专业的培训机构,专业的导师团队,优秀的教学质量,选对是很关键的事!
来极客程序员吧,成就你的梦想
看了有毛用。你不去练习,拿到实际运用,在看100本都没鸟用
我就是学Java的
交个朋友呗
你名字起的不行魔兽世界不行咯
游戏开发 java后端服务器 c++前台客户端
就这么被你吃了
你精通linux吗?,还是说你只是对c++语法很熟悉。嵌入式系统了解吗,怎么给芯片写boot,怎么载入系统。最重要还是linux
c+入门门槛高学习曲线抖,只要基础扎实,越到后面越吃香。java易入门,学精的没几个,到处是半吊子。
对,你们千万别来学C++,太难了
说的好像你学的多好一样
登录百度帐号推荐应用C/S框架-如何新建模块和业务窗体|C/S框架网
&nbsp|&nbspC/S框架-如何新建模块和业务窗体
一.定义模块编号和模块名称
在Interfaces模块内找到IModuleID.cs文件,定义如下图:
二.增加模块项目(Class Library)
三.增加模块主窗体
模块项目工程定义完毕,选中项目点右键->属性->生成->输出路径->设为:..\Debug\
三.增加模块主窗体(添加引用)
四.定义模块的特性
五.在模块内定义数据字典窗体
在项目工程点右键,添加->新项目->Windows Forms内选择继承的窗体->打开Inheritance Picker窗体->选择frmBaseDataDictionary->确定(OK).
五.在模块内定义业务窗体
在项目工程点右键,添加->新项目->Windows Forms内选择继承的窗体->打开Inheritance Picker窗体->选择frmBaseBusinessForm->确定(OK).
新增的数据字典(frmDataDict.cs)窗体如下图:
一切准备就绪,运行程序。
六.运行程序效果图
新增的模块主窗体(新测试模块)如下图:
新增的数据字典窗体(frmDataDict)如下图:
七.解决方案目录结构
八.问题解答
1. 我按照上面的步骤完成了,运行程序后找不着新建的模块?
答: a.确认Debug目录下有没有CSFramework_ADO2.MyTestModule.dll文件. 如果没有请选中项目, 右键打开Properties菜单,在Build页设置Output
Path 为..\Debug\
b.查看 AssemblyInfo.cs文件,是否有AssemblyModuleEntry属性
[assembly: AssemblyModuleEntry(ModuleID.MyTestModule, ModuleNames.MyTestModule,
"CSFramework_ADO2.MyTestModule.frmModuleMainform")]
c.如果主菜单内出现了模块菜单,但是导航条没显示模块
是因为模块的菜单的名称与模块名称不一致,在frmModuleMainform的构造器内定义如下:
public frmModuleMainform() { InitializeComponent(); //主菜单的名称必须与模块名一致 menuStrip1.Items[0].Text
= ModuleNames.MyTestM }
2. 现在已经成功运行,如何控制菜单的权限?
答:关于菜单权限有专栏介绍.
3.其它问题请联系}

我要回帖

更多关于 c 找不到指定的模块 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信