LabVIEW

 找回密码
 注册
查看: 96|回复: 0

[共享贴] LabVIEW动态调用VI的作用和实现细节

[复制链接]
发表于 2021-10-29 11:20:43 | 显示全部楼层 |阅读模式
USB-6009数据采集卡首发
为了说明状态机、动态调用的作用和动态调用的注意事项,设计如下小程序
首先从Excel文件中读取100个数,面板有两个按钮,一个可以将这100个数求和,另一个将每个数加1. 之所以设计这个看起来没什么用的程序,是因为逻辑上以及架构上和最近做的一个实际项目很接近,只是功能简化了很多,此外还有以下几个原因
4 X( }  O  M6 N! G
  • 动态调用VI的目的是为了优化内存,不过小程序不容易看出内存优化的状况。初始化时读取Excel,引入了其他程序,可以从Windows任务管理器里观察内存的占用情况
  • 对读取Excel的VI进行动态调用,可以表明附加文件(如本文中的Excel)路径和动态VI路径的获取方式,虽然它们在Windows中的同一个文件夹下,但获取路径的过程有细节上的区别。本文主要为了表明这一点。
  • 读取Excel的VI采用如图1所示的调用Excel属性节点和方法节点的方式,LabVIEW有一套和Excel交互数据的库,是收费的,外企很重视授权问题,我用的LabVIEW是授权的,在没有购买这个库的情况下还是采用比较原始的方式操作Excel。个人学习的话无所谓,NI官方为了推广似乎也不是很重视版权,不过企业使用还是不要带来不必要的麻烦。; t6 ^! k$ C& G# |( P7 R1 o
    9 N' D3 @! M. S5 i: i
1451943-20190110221457175-1686133385.png
图1

0 t5 ^. J( X7 q  ~3 U
进入正题。写好图1的读取Excel的VI后,建立两个项目,两个主VI分别用直接调用和动态调用的方式来调用它,构建一个简单的状态机,再加上一点简单的算法就可以了。待读取的Excel就是A1到J10单元格分别写下1到100. 具体见图2和图3. 图2中获取应用程序的类型是为了区分是以VI运行还是以exe运行。以exe运行时路径会多出一层虚拟文件夹,后面会有更详细的说明

; b( k& g& a) {- _
1451943-20190110221635965-1675040536.png
图2

' d! X/ L0 i) r  Z; X0 ^% V
1451943-20190110221731550-235438963.png

2 c' ?( _9 g1 l3 Y0 c$ E
因为是直接调用,所以当把Direct Call(即主VI)添加到项目中时,被直接调用的子VI自动出现在了“依赖性”目录中,Build完成后,把Excel文件拷到exe相同的目录,如图4
/ j; r9 K. V# }% i" m' e* X: k
1451943-20190110221928443-1709286608.png
图4
/ R( x0 L2 ^! z
生成exe也正常运行,不过可以看到如图5所示,在没有打开Excel文件的情况下,Excel进程正在运行。直到关闭exe应用程序,Excel进程才会自动结束。
而且直接调用时所有子VI也都被加载到内存中,如果是很多子VI组成的大型程序,会占用大量内存。尤其是当VI后期不再被调用时,这些内存也无法释放。
1451943-20190110222036502-879895950.png
图5
0 b6 _+ e# R3 ~( `$ W
下面来看动态调用。动态调用只在VI被调用时才加载进内存,调用完成后释放相应内存。
首先编写如图6的子VI,它被主VI直接调用,又作为主调函数动态地调用“Read Excel.vi”
1451943-20190110222154954-2069606621.png
图6

, ?# m: n: P# D+ C2 i7 G
然后主VI调用上面子VI时,需要传递的实参就是“Read Excel.vi”(即需要被动态调用的VI)的路径,以及要读取的Excel文件的路径。
这里VI路径这一项容易出问题,因为VI和Excel文件在同一目录,所以很自然的会写成如图7这样,用同一个根目录组合出两个路径。(只截图初始化部分,其余部分不变)
1451943-20190110222229472-752912640.png
图7
7 E0 V2 ~$ z( A
上面的VI运行起来完全可以实现我们需要的效果,如果点击白色运行箭头的过程中一直观察Windows任务管理器,可以看到Excel进程出现了1秒钟左右就又消失了,然后程序的功能也完全没有问题。于是开始生成exe。
创建的过程就没有直接调用那么顺利了,如图8所示,因为“Read Excel.vi”没有被直接调用,所以不会出现在“依赖性”里面,也就没有出现在这个工程里。显然无法继续Build
1451943-20190110222325086-2089717430.png
图8

& @. p0 ?& I' r
这个问题解决起来比较容易,既然“Read Excel.vi”没有自动进入工程,我们就手动把它添加进来,然后Build时放到“总是包含”里面,如图9,就可以生成exe了
1451943-20190110222400183-978115634.png
图9
  U5 W: `" e6 D5 \
Build完运行exe,结果如图10,找不到“Read Excel.vi”。而且通过第三条“动态VI路径”可以看出软件希望找到这个VI的完整路径并不存在,自然是找不到的。读不到Excel,后面的计算等功能自然就不能用了
1451943-20190110222437178-636158575.png
图10

" k7 t# A* A8 P
如果改成图11这种路径设置的方式,即只拆分一次路径再组合成动态VI的路径。exe运行界面第三个路径同样显示了系统寻找动态VI的路径,是在“动态调用.exe”这个虚拟文件夹,Build过程中把动态VI包含在了“总是包含”里,就是为了实现这个。
运行效果如图12,没有错误且可以实现功能
1451943-20190110222513935-1306863299.png
图11
1451943-20190110222543349-575475345.png
图12
, V# a& Z" W6 U/ F; t
总结一下本文要表述的要点
  • 动态VI调用使程序变得更复杂,但是对于比较耗资源且不频繁调用的VI,动态调用对优化内存很有帮助。本程序的读取Excel只在初始化时调用一次,读取到数据后不再被调用,且被调用时占用较多系统资源,是很适合使用动态调用的
  • 附加文件(如本文的Excel文件)的路径需要区分应用程序类型是VI(Deployment System)还是exe(Run Time System)。以exe运行时,因为多了一层虚拟文件夹,因此需要多拆分一次路径
  • 动态VI的路径不用区分应用程序类型,都是拆分一次。对于以VI运行,拆分一次之后就是VI所在的文件夹;对于以exe运行,拆分一次之后是虚拟文件夹,只要Build时把动态VI添加到“总是包含”即可。# ~6 R* Z2 n5 `% L- h7 D6 `( ^/ A

    % T! T( ^' J2 C' t

; n. a* a/ b' ^3 P
本程序设计一个动态调用读取Excel,就是同时涉及到了上面2,3两条,可以作对比参考。

8 v: h& t3 N3 m3 v3 M  |
最后提一下,如果程序是图7那种不正确的方式,只是会导致程序在没有动态VI的地方寻找它,我们只要把这个VI复制到程序希望找到它的位置,程序依然可以正常运行,如图13,即使客户机没有安装LabVIEW不能识别VI文件也可以。
1451943-20190110222614281-489166742.png

4 c" |6 f% B6 L
IDAQ-USB-6009数据采集卡
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|无图浏览|手机版|网站地图|虚拟仪器论坛 ( 沪ICP备13044638号-3 )

GMT+8, 2021-11-29 02:35 , Processed in 0.020863 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表