初始化主要就是将仪器功能组库和虚拟控件库挂接至仪器拼搭场、建立仪器功能索引表、与虚拟控件工具箱对应的虚拟控件索引表、进行消息的登记及建立消息的分发机制,建立统一数据池和全局数据区,定义系统的组态描述。图10-26是系统初始化流程图。
图10-25 基于组态的VMIDS结构
图10-26的流程包括相关消息的登记、消息分发机制的建立、建立一个高效的仪器功能索引表,使得在进行功能“赋予”和测试融合的过程中,能快速定位仪器功能,建立一个与虚拟控件库对应的虚拟控件接口函数索引表,作为操作各类基本控件模型的函数定位索引等。此外,还使用了哈希散列值索引,即在向功能索引表插入新节点时,如果哈希散列值有冲突项,则指向该冲突项的下一个节点,直到冲突项链的末尾,然后在冲突项链末尾插入新节点。
这里涉及几个基本的结构,其中功能库表节点结构为:
typedef struct_FUNC_BANK_
{
CString szDllName;//功能库名
CString szDllDeclare;//功能库描述
CList<FuncNode,FuncNode>FuncList;//输出参数表
}FuncBankNode
FuncBankNode结构中,szDllName(功能库名)szDllDeclare(功能库描述)定义了某个功能库的属性,FuncList定义了该功能库中的接口函数。其中FuncNode功能索引表节点结构为:
typedef struct_FUNC_
{
CString szFuncName;//功能函数名
CString szFuncDeclare;//功能函数描述
DWORD nMessageID;//功能函数消息号
DWORD nCurrentIndex;//哈希索引散列值
DWORD nNextIndex;//后一个冲突项
LPVOID pExtend;//扩展属性
LPVOID pSystem;//保留属性
}FuncNode
图10-26 系统初始化流程图
FuncNode结构中,szFuncDeclare(功能函数描述)主要是在进行功能“赋予”时,获得所需功能的相应信息,判断功能的类型,例如判断一个功能是一个接收数据的功能还是一个输出数据的功能等。szFuncName是具体仪器功能名称,用于获取功能库中的函数地址。nMessageID则保存了功能函数对应的消息号ID。随着功能组库及仪器功能的增多,如果不采取某种快速检索技术,那么在进行功能“赋予”和测试融合时,在功能索引表中查找相应的功能函数将变得非常费时,因此引入哈希索引散列值nCurrentIndex以加快仪器功能的快速检索与定位。哈希散列值是由szDllName(功能库名)及szFuncName(功能函数名)通过哈希算法计算而得,nCurrentIndex确定了该节点在功能索引表的位置。由于哈希算法计算出的散列值有可能产生冲突,即不同动态库、不同功能具有相同的哈希散列值,因此引入了一个解决这种冲突的域,nNextIndex表示具有相同散列值的下一个函数。pExtend(扩展属性)用于扩展接口定义。pSystem(保留属性),系统保留,当前版本中没有用到。
事实上,FuncNode结构主要针对默认接口函数。对于扩展接口,对于扩展接口,为了与前期版本结构的兼容,由FuncNode中的pExtend(扩展属性)描述,为了区分功能是默认接口还是扩展接口,或者是默认接口中的哪类接口,由szFuncDeclare(功能函数描述)属性来描述和区分,例如默认接口,主要有无参数接口、输出参数接口、输入参数接口等接口形式,与相应的控件对应。根据仪器功能库的设计一节的内容可以知道,系统定义了五类接口形式。
FuncNode.pExtend属性展开之后即可得到扩展接口的定义,其节点结构为:
typedef struct_FUNC_EXTEND_
{
int nInParamNum;//输入参数个数
CList<Param,Param>InParamList;//输入参数表
int nOutParamNum;//输出参数个数
CList<Param,Param>OutParamList;//输出参数表
int nReturnType;//返回参数类型
}FuncExtendNode
FuncExtendNode结构定义了完整的功能参数:输入参数个数、输入参数表、输出参数个数、输出参数表、返回类型。其中,Param是输入输出参数的统一定义,其结构为:
typedef struct_PARAM_
{
CString szParamDeclare;//参数描述
CString szParamName;//参数名称
int nParamType;//参数类型
PVOID pDefaultValue;//默认值
}Param
Param结构中,szParamDeclare描述参数的功能定义。szParamName定义了参数在功能库中的名称,这是虚参定义,只用于局域空间;对于实参来讲,在不同的局域空间,其名称可以是不同的。nParamType定义参数的数据类型,根据C++中的数据类型定义,并考虑到仪器开发和使用过程常用的数据类型,以及系统开发的方便性。定义的数据类型和类型编号如表10-3所示。
表10-3 数据类型与类型编号表
(www.xing528.com)
对于相应的指针数据类型,则原类型编号的基础上加10,作为该指针类型的编号。例如char∗数据类型的编号为12,float∗的编号为18。pDefaultValue表示该参数的默认值,因参数类型的不可预知性,所以pDefaultValue定义为指针类型,使用时,再根据nParamType来读些该指针的数值。
对于一个接口函数的使用者来说,只要获得了FuncExtendNode结构数据,就可以调用该接口函数了。
下面以FFT(float∗xi,float∗xr,int nSize,bool flag)函数的第一和第三个参数为例,说参数结构和扩展属性结构的读写。第一个参数参数的默认值为NULL,类型为float∗,即类型编号为18;第三个参数参数的默认值为1024,类型为int,即类型编号为5,于是有
……
//定义扩展节点
FuncExtendNode FFT;
FFT.nInParamNum=4;
FFT.nOutParamNum=0;
FFT.nReturnType=0;//表示没有返回值
//填充输入参数信息
Param param;
param.szParamDeclare=“傅里叶变换的虚部”;
param.szParamName=“xi”;
param.nParamType=18;
param.pDefaultValue=NULL;
InParamList.AddTail(param);//第一个参数
……
param.szParamDeclare=“傅里叶变换的长度”;
param.szParamName=“nSize”;
param.nParamType=5;
param.pDefaultValue=new int;
(int)(∗param.pDefaultValue)=1024;
InParamList.AddTail(param);//第三个参数
……
最终,系统得到具有如图10-28所示结构的功能接口函数表。
虚拟控件接口函数索引表节点结构如下:
typedef struct_CTL_
{
CString szDllName;//控件库名
CString szDllDeclare;//控件库描述
FARPROC pCreatePointer;//虚拟控件的创建接口函数
FARPROC pDeletePointer;//虚拟控件的删除接口函数
FARPROC pSavePointer;//虚拟控件的保存接口函数
FARPROC pLoadPointer;//虚拟控件的装载接口函数
FARPROC pSetRunStatePointer;//虚拟控件的运行状态设置接口函数
FARPROC pImportFuncTablePointer;//虚拟控件的接受功能索引表接口函数
CList<Param,Param>InParamList;//输入参数表
CList<Param,Param>OutParamList;//输出参数表
LPVOID pSystem;//保留属性
}CtlNode
其中,szDllName是虚拟控件基本模型库的名称。szDllDeclare则是对这一基本模型库的描述。后面6项是一个基本控件模型库与仪器拼搭场之间的基本接口,完成虚拟控件的创建、删除、保存、装载、运行状态设置以及接受功能索引表。InParamList、OutParamList是控件与外界进行信息交互的信号量,实现控件的功能组态、界面组态和通信组态,例如,对于虚拟按钮来讲,其输出参数至少有布尔量的状态输出。pSystem是一个扩展属性,目前保留,目的便于虚拟控件接口结构的扩展。这里因为虚拟控件基本库的数量不多,因此无需使用哈希散列索引。控件库也同样可建立类似于图10-27所示的功能接口表结构,这里不再列出。
图10-27 功能接口表结构
在完成两个表的创建之后,接下来就是创建一个所有功能动态库和虚拟控件动态库都能共享的缓冲区,用于实现某些相应的信号量、管道、互锁机制等及其他一些相关全局数据或控制量。同时,还要解决如何使功能索引表和虚拟控件表之间产生联系,也就是说虚拟控件库怎样才能接收到仪器功能,这里就用到了虚拟控件表节点中的pImportFuncTablePointer,通过这个接口地址,将功能索引表导入到各个基本虚拟控件库。建立虚拟控件工具箱,将控件功能库表与该工具箱建立连接对应关系。此外,还对仪器拼搭场进行必要的初始化,例如设置屏幕分辨率、设置仪器背景颜色等。下面专门介绍数据获取与管理的设计。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。