如何在CVI编译项中自定义宏实现条件编译



主要软件: LabWindows/CVI Development Systems>>LabWindows/CVI Full Development System
主要软件版本: 2009 SP1
主要软件修正版本: N/A
次要软件: N/A

问题:
客户想在CVI软件中,build的custom configurations里面添加新的编译项,当选择不同的编译项时,实现定义不同的宏,进而实现部分代码编译功能。如图1所示,选择TEST1时实现部分代码编译,选择TEST2时实现另一部分代码编译。为了实现这样的功能,该如何设置环境,或者说,在哪里设置?

图1 问题描述



解答:
1.宏的定义
        所谓宏,就是一些命令组织在一起,作为一个单独命令完成一个特定任务。计算机科学里的宏(Macro),是一种批量批处理的称谓。一般说来,宏是一种规则或模式,或称语法替换 ,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串)。这种替换在预编译时进行,称作宏展开。
        解释器编译器在遇到宏时会自动进行这一模式替换。对于编译语言,宏展开在编译时发生,进行宏展的工具常被称为宏展开器。宏这一术语也常常被用于许多类似的环境中,它们是源自宏展开的概念,这包括键盘宏和宏语言。绝大多数情况下,“宏”这个词的使用暗示着将小命令或动作转化为一系列指令。计算机语言如C或汇编语言有简单的宏系统,由编译器或汇编器预处理器实现。
2.条件编译
        软件工程中一个非常重要的问题是软件的可移植和可重用问题,例如在微机平台上开发的程序需要顺利的移植到大型计算机上去运行,同一套代码不加修改或经过少量的修改即可适应多种计算机系统。C语言作为软件工程中广泛使用的一门程序设计语言,需要很好的解决此类问题。为此ANSI C引入了预编译处理命令,主要规范和统一不同编译器的指令集合。通过这些指令,控制编译器对不同的代码段进行编译处理,从而生成针对不同条件的计算机程序。一般情况下,源程序中所有的行都参加编译。但有时希望对其中一部分内容只在满足一定条件下才进行编译,即对一部分内容指定编译条件,这就是“条件编译”(conditional compile)。
        条件编译指令将决定哪些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。条件编译指令一般有#if#else#elifendif#ifdef#ifndef指令,主要有以下几种形式。
(1) #if#else#elifendif的一般形式
#if 表达式1/宏名1
//语句段1
#elif表达式2/宏名2
//语句段2
#else
//语句段3
#endif
如果表达式1真或之前定义了宏名1,则编译语句段1,否则判断表达式2和宏名2;如果表达式2为真或之前定义了宏名2,则编译语句段2,否则编译语句段3
(2) #ifdef的一般形式
#ifdef 表达式/宏名
//语句段
#endif
作用:如果表达式真或之前定义了这样的宏名,则编译语句段。
(3) #ifndef的一般形式:
#ifdef 表达式/宏名
//语句段
#endif
作用:如果表达式假或之前没有定义这样的宏名,则编译语句段。
#else可以用于#ifdef和#ifndef中,但#elif不可以。
3. CVI实现步骤
        通过前面两节的介绍,大家应该对宏和条件编译已经有了基本的认识。这一章节主要介绍,如何在CVI中进行设置,在不同的编译项下添加自定义宏,实现条件编译。具体步骤如下:
        1) 如图2所示,点击Build->Configuration->Manage Configurations,将进入编译项窗口,如图3所示。CVI中有四种默认的编译模式:Debug,Release,Debug64和Release64。Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用,但无法使用Debug模式下的一些功能,例如设置断点、运用调试窗口等。Debug和Release生成32bit目标文件,Debug64和Release64生成64bit目标文件。
图2 进入编译项窗口
 
图3 编译项窗口
        2) 在编译项窗口中,点击Add,添加新的编译项,如图4所示,在弹出的窗口中定义该编译项的名称,如TEST1,然后点击”Build Option”按钮,进入配置窗口,对该编译项进行配置。关于Debug、Release、32-bit和64-bit的区别在前文中已经进行了介绍,用户可以根据实际需要进行自定义。一般情况下,默认选择Debug和32-bit。
图4 定义新的编译项名称
        3) 如图5所示,在配置窗口最下面“Compiler Defines”的输入框中,可定义该编译项下的宏变量。定义方式有两种,直接定义宏名或者定义一个表达式。如果直接定义一个宏名,如TEST1,那么对应到主程序中的条件编译语句即是#if TEST1;如果定义一个表达式,如TEST1==0,那么对应到主程序中的条件编译语句即是#if TEST1==0。需要注意的是,在此处定义的宏名或者表达式都是以”/D”开头。
图5 定义该编译项下的宏变量
        4) 重复步骤2)和3),添加TEST2和TEST3两个编译项,分别对应TEST2和TEST3两个宏变量。然后在主程序中利用条件编译语句,即可实现选择不同的编译项时,对代码进行条件编译。如图6所示的主程序代码中,TEST1和TEST2使用了#if和#ifdef两种条件编译指令,TEST2和TEST3则使用了直接定义宏名和定义表达式两种宏变量定义方式。为了验证不同条件编译指令以及不同宏定义方式的可行性。
图6 主程序条件语句编写
        对该程序进行测试,当在Build->Configuration下选择TEST1进行编译时,程序最终只编译#if TEST1下的语句,程序运行结果如图7所示:
图7 TEST1编译项下的运行结果
        重复上述操作,分别选择TEST2和TEST3进行编译,程序运行结果如图8和9所示:
图8 TEST2编译项下的运行结果
图9 TEST3编译项下的运行结果
       从结果中可以看出,通过在不同的编译项下定义不同的宏变量,结合条件编译指令,可实现对程序代码的条件编译。其中,TEST1和TEST2分别使用了#if和#ifdef两种条件编译指令,TEST2和TEST3则分别使用了直接定义宏名和定义表达式两种宏变量定义方式。
        这个时候可能有人会问,如果我想在一个编译项下,对多个宏进行条件编译,是否可行呢?答案是肯定的。只需要在一个编译项下定义多个宏变量即可。如图10所示,重新添加一个编译项TEST4,在配置窗口 “Compiler Defines”的输入框中定义TEST1和TEST2两个宏变量,需要注意的是,两个宏之间要以空格隔开。这个时候在Build->Configuration选择TEST4编译项,即可同时对#if TEST1和#ifdef TEST2下的语句进行编译。
图10 一个编译项下定义多个宏
4. 总结
        本文主要介绍了宏和条件编译的基本概念,以及如何在CVI的不同编译项中自定义宏,并结合条件编译指令实现代码的条件编译。条件编译指令一般有#if#else#elifendif#ifdef#ifndef。在CVI的编译项中,可以通过定义宏名或者表达式两种方式实现宏变量定义,但必须与主程序中的条件编译语句相一致。此外,在CVI中的一个编译项下支持定义多个宏变量,从而实现多个宏变量的条件编译。


相关链接:

附件:





报告日期: 12/01/2015
最近更新: 12/02/2015
文档编号: 74018BA0