如在LabWindows/CVI中打开一个header/include (.h)文件,可使用Options»Generation Function Tree命令生成函数面板。 为了清晰地定义函数树形结构,应使用header文件标签。 另一方面,如从一个不包含header文件标签的header文件生成函数面板,所有函数面板都将位于仪器树形结构的根目录,所有参数都被处理为输入。
图1.Generate Function Tree对话框
例如,如从下列header文件生成函数面板,得到的函数面板文件(.fp)如图2所示。注意观察函数面板树为扁平式结构。
int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);
float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);
图2.基于没有标签的header文件生成函数面板
注意:Generate Function Tree对话框中的默认限定符必须与源header文件的默认限定符一致。
使用///关键字标识的header文件标签,可提高下列任务的灵活度:
首先,可使用类在.fp文件中创建层次结构。下列标签表示类的开始:
/// -> Class Name
下列标签表示类的结束:
/// <- Class Name
注意:标签的类名是可选的,类名可以使代码具有更好的可读性。标签->
和<-
可以嵌套。
/// -> Integers
int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);
/// <- Integers
/// -> Floats
float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);
/// <- Floats
图 3为上述代码生成的函数面板。
图3.生成的函数面板,使用->标签
为了保证生成的函数面板样式一致,LabWindows/CVI对函数面板进行下列操作:
由于自动分词机制,生成的函数面板名称可能与预期的名称不同。要更改生成的函数面板标题 ,请使用XCHG标签。您也可以指定多个替换字符串,以半角逗号分隔。
注意:您也可以使用PXCH标签替换函数面板控件中的字符串。
/// XCHG Fn/Function
/// -> Integers
int __stdcall fn1(int a);
int __stdcall fn2(int b);
int __stdcall fn3(int a, int b);
/// <- Integers
/// -> Floats
float __stdcall fn4(float a);
float __stdcall fn5(float b);
float __stdcall fn6(float a, float b);
/// <- Floats
/// XCHG
图4为上述代码生成的函数面板。
图4.生成的函数面板,使用XCHG标签
函数面板生成器不包含编译器,不解析header文件中的数据类型,如果数据类型为非ANSI数据类型,会产生语法错误。为了避免语法错误,可使用ADDT标签,使函数生成器了解在header文件中使用的自定义数据类型。
/// ADDT int8
/// ADDT uInt8
函数生成器将把函数面板的类型名称、数组和指针派生类型添加至函数面板。
int8 | uInt8 |
默认情况下,函数面板生成器创建输入控件。如函数面板生成器检测到枚举类型,将为参数自动创建一个下拉列表控件,可使用RNG、SLD、BIN标签创建其他类型的控件。
每个标签都需要两个参数,由斜杠分隔。第一个参数是参数位置(从1开始的索引),第二个参数是可选的。如果函数参数数据类型为枚举,可表示枚举名称。
注意:BIN标签只能关联至包含两个值的枚举型。
typedef enum {
ON=1,
OFF=0,
} MyBinaryEnumType;
/// BIN 1
int __stdcall fnX(MyBinaryEnumType binaryInput);
图5.Binary控件
如果要使用一组#define预处理器命令定义的值,可以使用ENUM将这些值组合在一起。
注意:#define值的后面必须留一个空行,这样生成器才知道已到达枚举型的结尾。
/// ENUM enum1
#define ON 1
#define OFF 0
/// ENUM enum2
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4
/// BIN 1/enum1
/// SLD 2/enum2,3/enum2
/// RNG 4/enum2,5/enum2
int __stdcall fnX(int a, int b, int c, int d, int e);
图6显示了基于上述代码生成的控件。
图6.使用BIN、SLD、RNG标签生成控件
如要为现有的枚举型添加默认值,可使用EHDV(slider控件、binary控件)。生成器将把新的值添加在值列表的顶部,标签为"Default",控件将被设置为指定的值。
typedef enum {
kLeftAligned=0,
kRightAlighed=1,
} AlignmentEnumType;
/// SLD 1
/// EHDV 1/-1
int __stdcall fnX(AlignmentEnumType alignment);
图7显示了基于上述代码生成的控件。
图7.使用EHDV标签生成的控件
如要为ring, binary, slider控件创建不同的值标签,可为每个枚举值添加注释。生成器将把枚举值替换为注释文本。
注意:请不要在枚举型注释中使用分号。
typedef enum {
kLeftAligned= 0, // Left aligned
kRightAlighed=1, // Right aligned
} AlignmentEnumType;
/// SLD 1
/// EHDV 1/-1
int __stdcall fnX(AlignmentEnumType alignment);
图8显示了基于上述代码生成的控件。
图8.在SLD标签中使用注释
使用OUT标签定义输出参数。输出参数只能是指针和数组。使用其他数据类型会导致错误。
/// OUT 2,3
int __stdcall Sphere_Calc(float radius, float *surface, float *volume);
图9显示了基于上述代码生成的控件。
图9.使用OUT标签生成的控件
函数面板生成器创建空输入和空输出,所有ring、binary、slider控件的默认值为数据项的第一项。如要改变参数的默认值,可使用DFLT标签。
/// OUT 2,3
/// DFLT 1/1.0,2/&surface,3/&volume
int __stdcall Sphere_Calc(float radius, float *surface, float *volume);
图10显示了基于上述代码生成的控件。
图10.用DFLT标签生成的控件
如要在函数面板上使用特定的参数类型,可使用PTYP标签,将数据类型从ANSI-C数据类型转换为函数面板上的其他有效类型。例如,声明为void*的一个函数参数,用来当作数值数组。可将该数据类型由void*改为LabWindows/CVI的Numeric Array类型。
/// PTYP 1/Numeric Array
float __stdcall CalcArrayMean(void *array, int dataType);
图11显示了基于上述代码生成的控件。
图11.使用PTYP标签生成控件
.SUB文件通常在IVI驱动程序中用于特定的仪器属性。 如要求将仪器要使用SetAttribute或GetAttribute函数,在.SUB文件中,属性参数使用ERNG标签,值参数使用PTYP标签。对于属性参数,函数生成器将创建一个空的ring控件。当加载仪器完成后,ring控件的参数将被.SUB文件中的内容填充。对于值参数,函数生成器将把参数类型从void*转换为LabWindows/CVI的任意类型。
注意:.sub文件的结构可以在Instrument Driver Interactive Developer Interface Specification(仪器驱动程序交互式开发接口规范)的第7章中找到。
/// ERNG 1
/// PTYP 2/Any Type
/// OUT 2
int __stdcall GetAttribute(int attribute, void *value);
注意:.SUB文件必须与其关联的.fp文件位于同一文件夹中,并且具有通用的根名称。
在本例中,我们将使用附件中的FPGen.sub 文件中的内容来填充仪器的属性。 生成函数面板后,打开GetAttribute函数并选择Options»Operate Function Panel (F9)。图12显示了基于上述代码生成的控件。
图12.使用ERNG标签生成的控件
在某些情况下,可能需要在函数声明中使用可变参数。如需在函数面板上添加其他值,则可以使用VARG标签。
/// VARG int/More Numbers Ending With Zero
int __stdcall Sum(int number, ...);
图13显示了基于上述代码生成的控件。
图13.使用VARG标签生成的控件
在函数面板上使用可变参数时,可将第一个数值放在第一个输入控件中,其他数值用逗号分隔,后接一个0,放在第二个控件中。函数调用如下:
Sum(1, 2, 3, 4, 5, 0);
图14.基于数列生成的控件
函数面板参数可以进行其他自定义。 参数控件右边的"..."按钮,表示自定义。要自定义参数,请使用CUST标签。指定参数位置、包含所需自定义函数的DLL和入口点名称。 详细信息请参考LabWindows/CVI帮助中的creating customization functions and DLLs。
注意:自定义DLL必须位于系统路径或仪器所在的同一文件夹中,才能被准确定位。 DLL规范中可使用相对或绝对路径。
/// CUST 1/cviLibCust.dll/SelectAnyFile
int __stdcall SaveDataToFile(char filePath[], void *data);
在本例中,我们将使用附加的 cviLibCust.dll 文件。生成函数面板后,打开SaveDatatoFile函数并选择Options»Operate Function Panel (F9)。如单击自定义按钮(或按下回车键),则会打开一个Open File对话框,如图15所示。
图15.自定义参数
如要给函数面板添加说明信息,可添加仪器帮助、类帮助、函数帮助,甚至可以为参数添加帮助。分别使用HFP、HCL、HFUN、HPAR、HRET标签。帮助信息可以为纯文本或HTML,必须保存在一个文件中。 每个文件名关联至一个或若干个帮助生成标签。
/// HFP FPfileHelp.htm
/// HCL IntegerClassHelp.htm
/// -> Integers
/// HFUN Fn1Help.htm
/// HPAR 1/ParameterAHelp.htm
int __stdcall fn1(int a);
/// HFUN Fn2Help.htm
/// HPAR 1/ParameterBHelp.htm
int __stdcall fn2(int b);
/// HFUN Fn3Help.htm
/// HPAR 1/ParameterAHelp.htm,2/ParameterBHelp.htm
int __stdcall fn3(int a, int b);
/// <- Integers
注意: 该例中的HTML文件在文档附件中。
生成函数面板文件后,可将光标停留在fn3函数的第一个参数,从右键菜单中选择Edit » Show Prototype或者按下Ctrl+Shift+Space,提示框中将出现函数的原型。
单击问号按钮或F1,可查看参数帮助。
图16.HTML函数帮助
LabWindows/CVI开发环境有助于提高ANSI C应用程序开发效率,并提供源代码标签,可基于header文件生成函数面板,可为函数面板创建HTML文档。