动态链接库

CLN节点 Call library function node

动态链接库的加载方式又分”动态”与”静态”两种.这里的动态和静态是指应用程序运行时,动态链接库代码被载入内存的方式.常用的方式是静态加载,指动态链接库在应用程序启动时随应用程序一起被载入内存.而动态加载方式是指,应用程序启动时并不载入动态链接库,只有在使用到动态链接库中某个函数时,才把动态链接库载入内存。
调用库函数节点点常简称为CLN 节点,是英文Call Library Function Node 的缩写。
在LabVIEW 中调用DLL 的函数,最大的困难在于把函数参数的数据类型映射为相应的LabVIEW 中的数据类型。在手工设置CLN 节点前,可以优先考虑使用导入共享库工具,以自动生成配置CLN 节点。这个工具在”工具→导人→共享库”菜单项中,专门用于把DLL 中的函数包装成VI。这个工具可能无法直接处理一些非常特殊的数据类型(如字符串数组〉和函数(如回调函数) ,但在大多数情况下,都能够把DLL 中的函数包装成可以正确运行的VI。
如果DLL 是C++ 编写的,并且使用了C++ 的类作为接口,这样的DLL 是没办法在LabVIEW 中直接调用的。CLN 节点只能调用符合标准C 语言函数接口的DLL. 着项目中必须使用这个C++ DLL ,则可以在其上再用C 语言写一个C 接口DLL ,作为它和LabVIEW 之间的中间层. LabVIEW 调用这个中间层DLL 提供的函数,中间层函数再调用C++接口的DLL函数。
在系统路径下的DLL ,直接输入文件名即可,否则需要全路径。若没有选中”在程序框图中指定路径”,则DLL 是被LabVIEW 静态加载到程序中的,也可被称为LabVIEW 程序静态调用了这个DLL。调用了这个DLL的VI 被装入内存时.DLL 也同时被装入内存。若选中了”在程序框图中指定路径”选项,那么对话框中配置的DLL 就是元效的.CLN 节点会多出两个”路径”接线端,以便在程序框图中输入DLL 的路径。
image.png
此时. LabVIEW 是动态加载DLL 的,或者说LabVIEW 是动态调用DLL 的。因为在VI 运行到这个CLN 节点之前,都不能确定输入的”路径”是什么,所以自然也无法加载相应的DLL. 只有当运行到这个CLN节点时. LabVIEW 才把要用到的DLL 装入内存。在这个CLN 节点运行结束后,LabVIEW 并不会立即把DLL 卸载出内存.如果后续的CLN 节点也使用了这个DLL 文件,就不需要再重新加载了.只有当程序传一个空路径给CLN 节点时.LabVIEW 才会把已经加载的DLL 文件卸载。
加载DLL 文件通常是一个比较耗时的工作.采用静态加载方式,程序所用到的DLL 在程序启动时都被装入内存,程序启动时间比较长。而使用动态加载方式,程序运行到需要用到DLL 的时候才被加载,缩短了程序的启动时间,把这部分时间转移到了程序运行中。
“在UI 线程中运行”是指在UI 线程〈即界面线程〉中运行被调用的函数. LabVIEW 程序不论多么复杂,都只有一个界面线程.这个线程用于处理所有与界面相关的工作,如显示一个数据、产生一个用户事件等.由于程序中只有一个界面线程,如果把多个被调用的函数都设置为在界面线程中运行,就可以确保这些函数在同一线程内运行.可以按照以下判断方法选择CLN 节点中的线程设置.如果被调用的动态链接库是多线程安全的,则选择”在任一线程中运行飞否则,动态链接库就不是多线程安全的,就得选择”在UI 线程中运行” 。选择在任一线程中运行一个DLL 函数,程序的运行效率比较高。
“调用规范(Calling convention) 用于指明被调用函数的参数压栈规范。CLN节点支持两种规范: stdcall 和C call. 它们之间的区别在于,stdcall 由被调用者负责清理堆栈,C call 由调用者清理堆栈。如果调用规范设置错误,则可能引起LabVIEW 崩溃,所以一定要小心。反过来说,如果LabVIEW 调用DLL 函数时出现异常,首先就应该考虑这个设置是否正确。

简单数据类型参数的设置

在DLL 和LabVIEW 之间传递参数,最常用的3 种数据类型是数值、字符串和数值型数组。
1)数值类型
“4 字节单精度”数据类型对应C 语言中的float 数据类型。对应关系在《LabVIEW宝典》P258页。
C 语言中经常在函数间传递指针或者数据的地址。在32 位的程序中,可以使用int32 数值来表示指针。因此,当需要在LabVIEW 中传递指针数据时,可以使用132或U32 数值类型来表示这个地址类型的数据。但是,在64 位的程序中,数据的地址只能使用I64 或U64 来表示。这样在一个调用了DLL 函数并且函数参数中有地址型数据的VI.如果使用固定数据类型的数值来表示地址,则要准备两份代码。解决此问题的方法就是在该选项卡的”类型”列表框选择使用LabVIEW 中的新数据类型有符号或元符号”指针大小整形”。这个数据类型的长度在不同的平台上会自动使用32 位或64 位长度。
image.png
如果在C 语言函数参数声明中有const 关键字,则可以选中”常量”选项。LabVIEW把一个数据传递给DLL 中的函数时,通常需要为数据生成一份拷贝,让DLL函数使用这个拷贝数据。这样做的目的是防止数据在DLL 中被修改,外部程序又不知道,因而引起错误设置”常量”属性,就说明这个参数一定不会在DLL 中被改动,LabVIEW 可以不为它生成一份拷贝,以节约内存。
2)布尔类型
在C 语言中,有多种表示布尔类型的数据类型,如bool 、BOOL 等。它们的存储长度可能不相同,有的用一个字节表示,有的用4 个字节表示。在使用时需要查看一下在被调用的DLL 文件中布尔类型是以何种长度存储的,再使用对应的数值数据来表示它。
image.png
3)数值型数组
对于数组的传递. LabVIEW 只支持C 数据类型中的数值型数组。在CLN 节点中配置数组型参数时,选择”类型”为”数组”,这是指参数的类型3 然后还要选择”数据类型飞这是指数组元素的数据类型,官可以是任何一种数值类型.
当函数的输出参数为数组时, 一定要为输出的数组数据开辟存储空间.开辟数据空间的方法有两种:第一种方法是创建一个长度满足要求的数组作为初始值传递给参数。这个输入数组的内容对程序而言是无效的,它只被用来表示应该为输出数组分配的内存空间的大小,以确保输出数据都被保存在这个合法的内存空间中。第二种方法是直接在参数配置面板上设置。在”最小尺寸”文本框中写入一个固定的数值,则LabVIEW 按此大小为输出的数组开辟内存空间。在”最小尺寸”文本框中参数可以输入一个固定数值,此外,如果该CLN 节点调用的参数中有整型参数,则这些参数的名称就会出现在该文本框的选择项中’也就是说,也可以选择某个参数作为”最小尺寸”这样LabVIEW 就按照所选参数运行时的输入值来开辟相应大小的空间。
如果没有给输出数据分配内存或分配的空间不够大,程序运行时就可能出现数组越界的运行错误. LabVIEW 会莫名其妙崩溃.更糟糕的是. LabVIEW 也许并不是在出现数组越界错误的瞬间崩溃的,而往往是在其之后的某个不确定的时刻崩溃。如果意识不到程序中有这种错误或者程序中有很多个类似的CLN 节点,那么,调试并查找排除这一错误可能要花费大量的时间和精力。
4)字符串类型
字符串的使用与数组是非常类似的,设置见表5.4 。实际上,在C 语言中字符串就是一个18 数组.
image.png

结构型参数的设置

LabVIEW 的簇只能是1字节对齐的。因此.C 语言中,非1字节对齐的结构与Cluster 对应时,必须做适当调整, 才可使数据正确传输。
image.png
image.png
Windows API一般使用stdcall ,标准C的库函数大多使用C call。如果函数声明中有类似“_ stdcall”这样的关键字,则它就是stdcall的。
LabVIEW把一个数据传递给DLL 中的函数时,通常需要为数据生成一份拷贝,让DLL函数使用这个拷贝数据。这样做的目的是防止数据在DLL中被修改,外部程序又不知道,因而引起错误。设置”常量”属性,就说明这个参数一定不会在DLL中被改动,LabVIEW可以不为它生成一份拷贝,以节约内存。
image.png
image.png

Active X

通过定义容器〈调用ActiveX 控件的程序〉和组件(ActiveX 控件) 之间的接口规范,用户可以很方便地在多种容器中使用Active 控件,而不必修改控件的代码. ActiveX 控件使得网页通过脚本和控件交互,产生更加丰富的效果。

使用ActiveX控件

WebBrowser的属性方法:WebBrowser控件概述
image.png
image.png

ActiveX自动化

image.png
image.png

.NET

类似于ActiveX控件
应用:
1.使用.NET数据类型(动态数组)
2.使用.NET调用系统功能
3.使用.NET调用内置对话框
4.利用.NET创建托盘程序

EXE