LabVIEW开发LabVIEW类
从概念上来说,LabVIEW面向对象编程和其它面向对象编程语言相似。但由于LabVIEW是数据流图形化编程环境,LabVIEW对类数据的操作和交互,以及LabVIEW类代码的调试方法和其它语言有所不同。
LabVIEW中的对象由值来传递,而不是由引用来传递。LabVIEW按照簇和数组的操作规则创建对象的副本。
构造函数和析构函数
构造函数和析构函数在LabVIEW面向对象编程中是隐含的。不需要调用构造函数来对LabVIEW类数据进行初始化。每当需要对一个类进行初始化时,LabVIEW会调用一个默认的构造函数。通常情况下,类在前面板的相应控件或程序框图的相应常量中初始化。LabVIEW用私有数据控件中设定的默认值来对类的值进行初始化。当LabVIEW不再需要LabVIEW类中的信息时,LabVIEW将以处理簇和数组同样的方法进行内存释放。如需将类数据设定为其它值,必须创建一个成员VI以对类数据设定新值。例如,若在创建汽车类时,将其中齿轮数量的默认值设定为3,而又希望对卡车类从汽车类继承而来的齿轮数量指派一个不同的值,这时就必须创建一个成员VI以改变汽车类的值。设置新值的另一种方法是:创建一个没有输入,以类为输出的成员VI,将需要指派给齿轮数量的值设定在输出类中,从而可创建一个以该输出类为数据类型的程序框图常量。
平化和还原数据
LabVIEW以平化数据的形式存储数据。平化至字符串及从字符串还原函数可以处理所有的类数据类型。LabVIEW自动平化和还原数据。所有类型描述符保留了LabVIEW中已平化数据的类型,而LabVIEW类的平化数据本身不但保留了类型信息,而且保留了类的版本信息。由于LabVIEW类保留了用于还原LabVIEW类的相关信息,如果LabVIEW类因被移动或删除而无法找到,LabVIEW将无法还原数据并将显示错误信息。类似于LabVIEW丢失子VI时的情形,打开成员VI时,若某控件的LabVIEW类数据已丢失,该控件将变灰。断开控件所对应的LabVIEW类被加载之后,数据将被还原而控件将不再被断开。
注: 也可使用平化至XML和从XML还原函数处理类数据。
实施数据变异
若试图向LabVIEW类控件中写入数据的LabVIEW类比内存中的LabVIEW类版本更新,则被写入的控件将发出警告。当LabVIEW类私有数据控件的数据类型或类的继承关系发生改变时,该类的版本号将被增大。通过类属性对话框,可查看LabVIEW类的版本号。出现以下情况时,LabVIEW将自动增大类的版本号:
LabVIEW类的继承关系发生改变。
LabVIEW类的私有数据控件发生改变。私有数据控件的改变包括:添加、替换、重新排序或删除控件;改变控件的表示法;更新已修改的自定义类型。
在新版本的LabVIEW中加载旧版本的LabVIEW类。
通过类属性对话框可手动增大类的版本号。递增的版本号表示类版本的更新。
若对一个类进行重命名,则LabVIEW将把该类当作一个新类,删除该类的变异历史,并将版本号重新设定为1.0.0.0。执行以下任意一种操作时,LabVIEW类将被重命名:
通过下拉菜单的文件»另存为,对类进行重命名。
将类移入所属库。
将类移出所属库。
重命名磁盘上的.lvclass文件。
注: 如不作任何改动,将类改回原来的类名,则改回原名的类和原类仍有所不同,因为原类的变异历史已经丢失。例如,假设将汽车类重命名为“汽车#1类”,然后将类名从“汽车#1”改回“汽车”,则新的汽车类和原来的汽车类不再是同一个类。
对使用LabVIEW类开发应用程序的LabVIEW类用户来说,LabVIEW跟踪LabVIEW类的版本号是很有用的。例如,假设应用程序中有一个LabVIEW类,该类的私有数据控件使用了无符号32位整型。然而,LabVIEW类开发人员发送的某个版本的LabVIEW类中,私有数据控件中的数值控件变成了双精度浮点型。由于LabVIEW跟踪了版本的变化,并能对所有LabVIEW类的数据进行平化和还原,用户可以直接用新版本替换旧版本,不必作任何修改即可运行程序。
注: 如将数据从某个LabVIEW类的未来版本还原,LabVIEW将返回错误。例如,当内存中某个LabVIEW类的版本号为1.0.0.2,而数据的版本号为1.0.0.3时,将可能出现该错误。
LabVIEW采取如下方式处理LabVIEW类不同版本数据的变异:
如从LabVIEW类层次结构中移除一些类,则LabVIEW将从原来的类层次结构中删除这些类的平化数据。例如,假设类C继承了类B,而类B继承了类A。如将类C更改为直接继承类A,则LabVIEW将删除类C中来源于类B的平化数据。
如在LabVIEW类层次结构中添加新层,则LabVIEW将把被添加类的默认数据插入到原来的类层次结构中。例如,假设类C和类B都继承了类A。如将类C更改为继承类B,则LabVIEW将对类C插入类B的默认数据。
如在类私有数据簇的末尾(按tab键顺序)添加一个元素,则LabVIEW将还原旧的数据并添加类的默认数据。
如在类私有数据簇中删除一个元素并且不添加任何新元素,则LabVIEW将还原旧的数据并删除该元素相关的信息。
如改变类私有数据簇的tab键顺序,则LabVIEW将对还原后的相应数据进行重新排序。
如在同一次修改中添加、删除、替换或重新排序类的私有数据簇,LabVIEW将创建并执行一个过程,通过合并以上步骤对数据实施相应的变异操作。
LabVIEW类不同版本的变异总是按顺序(例如从版本1.0.0.2到1.0.0.6)实施的。
注: 当类的版本号增大以后,将无法对LabVIEW类进行恢复。由于没有足够的信息,LabVIEW无法撤消LabVIEW类的输入和显示控件中数据的更改。如需恢复当前的更改,请不要保存任何更改。卸载该类及所有引用该类的VI,然后从磁盘重新加载该类。
关于编辑LabVIEW类时,LabVIEW进行数据变异的详细信息,见ni.com的技术支持文档。
强制转换LabVIEW类
通过转换为通用的类函数可将LabVIEW类向上转换;通过转换为特定的类函数可将LabVIEW类向下转换。这些函数还可用于对包含继承层次结构的引用数据类型(例如VI服务器控件引用)进行操作,功能是一样的。使用“转换为通用的类”函数并不改变数据,但传递数据的连线类型将被改变。但是,该函数在VI运行时不起作用。对那些按照严格代码规范需要避免数据转换的程序员而言,“转换为通用的类”函数提供了一种消除强制转换点的方法。
“转换为特定的类”函数不改变数据,除非出现错误。如运行时连线上的数据不是更为特定的类,则该函数将返回一个错误并且输出数据将是连线类型的默认值。“转换为特定的类”函数的主要用途是对父类的值作类型检查。通常程序员将同一个父类连接到多个“转换为特定的类”函数,每一个连线导向一个更为特定的类,哪一个“转换为特定的类”函数不报错,便执行该函数之后的代码,从而实现根据类型检查结果运行不同的代码。这种方法相当低效。如需用这种方法作类型检查,并拥有修改父类的权限,可在父类添加一个动态成员VI,并让每一个子类根据功能需要重写这个动态成员VI。
如LabVIEW在运行时检测到用户将子类对象连接至接受父类对象的子VI,LabVIEW将自动把子VI输出向下转换为子类对象。自动向下转换不必使用“转换为特定的类”函数。但是,只有LabVIEW确保连接至子VI的类对象与子VI接受的输入兼容时,自动向下转换才发生。例如,如将类对象保存在变体中,然后将变体数据连接至子VI,LabVIEW不能确保子VI包含的数据与变体原本存储的数据为同一种类型。使用保留运行类函数帮助LabVIEW检查连接至子VI的类对象与子VI接受的类对象为兼容对象。如两个对象不兼容,函数将返回错误,并将类的输出数据设置为子VI接受的父对象。也可将该函数与数据值引用配合使用。数据值引用读取/写入元素边框节点必须预留运行类型。可使用“保留运行类”函数检查连接至“数据值引用写入”节点的类对象是否与连接至“数据值引用读取”边框节点的类对象相互兼容。
注: LabVIEW无法自动向下转换递归子VI。如在动态分配VI的程序框图上或在元素同址结构中调用递归子VI传递数据值引用时,自动向下转换会引起调用VI的断开。在递归子VI的程序框图上使用“保留运行类”函数,验证连接至子VI的类与子VI接受的类是兼容的。如两个类兼容,在递归链之外调用VI不会使VI断开。
锁定和解除锁定LabVIEW类
通过锁定LabVIEW类可阻止LabVIEW类用户查看那些作为应用程序内部实现的成员VI。锁定LabVIEW类可避免 访问私有成员VI,以免将错误引入应用程序。与项目库类似,为LabVIEW类添加密码保护不会为成员VI添加密码保护。必须对类的成员VI单独设置密码保护。
如一个LabVIEW类被锁定,则当光标在类连线上移动时,即时帮助窗口中仅显示连线数据类型。当光标在一个未锁定的LabVIEW类上移动时,即时帮助窗口将显示该类的私有数据,以及该类所有未锁定的父类的私有数据。类似规则也适用于LabVIEW在“通用探针”上显示的信息。关于对LabVIEW类使用“通用探针”的相关信息见在LabVIEW类中使用探针。
注: 请注意,光标停留在LabVIEW类连线和停留在LabVIEW类控件时,即时帮助窗口中显示的信息是不同的。LabVIEW类控件为最终用户提供类的说明信息,而LabVIEW类连线则为LabVIEW类用户提供关于数据类型的补充信息。
LabVIEW类用户仅可查看开发人员提供的信息,因而开发人员须在开发LabVIEW类时向用户提供足够的文档信息。在类属性对话框中可添加类的说明信息,在成员VI各自的VI属性对话框中,可添加成员VI的说明信息。
在LabVIEW类中使用探针
通用探针和自定义探针可用于调试LabVIEW类。
对LabVIEW类连线可使用通用探针。LabVIEW类连线上的通用探针显示了运行时该类的类名、类的私有数据和该类所有父类的私有数据。如对一个已锁定的LabVIEW类使用通用探针,探针将仅显示运行时该类的类名,以及类层次结构中未锁定的私有数据。在下图中,位于左侧的“汽车”类被锁定,LabVIEW不显示类的私有数据:齿轮数量、车门数量、颜色、制造和型号。“卡车”类未被锁定,因而LabVIEW显示该类的私有数据。请注意,LabVIEW此时并不在通用探针上显示卡车类从汽车类继承而来的私有数据,因为汽车类已被锁定。
根据需要,也可为LabVIEW类创建自定义默认探针。仅可对确定类型或祖先类型的LabVIEW类连线使用自定义探针。LabVIEW类开发人员可创建能够直接显示类私有数据,并作为类成员VI的自定义探针。LabVIEW类用户可创建自定义默认探针,用于显示类的“公共”型方法可显示的任何信息。
LabVIEW开发人员可为LabVIEW类用户将自定义探针设置为默认探针。已锁定的LabVIEW类的通用探针不允许LabVIEW类用户访问任何关于数据值的信息,因为数据是私有的。类开发人员可创建自定义探针,再将它们设定为LabVIEW类的默认探针以提供给类用户,通过这种方法,开发人员锁定类之后仍可适当地将类中数据显示给类用户。自定义探针必须是LabVIEW类的成员,LabVIEW类开发人员才可将它设定为默认探针。
向其他开发人员和用户发布LabVIEW类
LabVIEW类开发人员可向其他类开发人员和类用户发布LabVIEW类。开发人员可通过多种方法发布LabVIEW类,可选择最符合需求的方式。可用应用程序生成器来创建zip文件以发布一个或多个类。也可在发布之前锁定LabVIEW类,从而限制LabVIEW类用户对私有数据和成员VI的访问。锁定LabVIEW类有助于防止将错误引入应用程序中。锁定LabVIEW类有助于防止将错误引入应用程序中。
提示: 也可通过.NET互操作程序集访问LabVIEW类。LabVIEW可为指定的LabVIEW类生成相应的.NET类,可通过.NET程序集访问.NET类。
需要说明的是,上述的例程和文档,都是可以下载的,双击即可打开,其中压缩文件是可以采用粘贴复制的方式,拷贝到硬盘上。这不是图片,各位小伙伴看到后尝试一下,这个问题就不用加微信咨询了。有关LabVIEW编程、LabVIEW开发等相关项目,可联系们。
楼主最近还看过