调用我的DLL为什么会导致LabVIEW崩溃?
问题:
当我使用调用库函数节点调用我的DLL时,LabVIEW崩溃了,会是由于什么原因?
解答:
有一些不同的可能原因会导致LabVIEW在调用dll函数的时候崩溃:
确认您选择了和DLL相同的调用规范
使用
C调用规范时
,调用方负责清空堆栈。使用
标准调用规范时
,被调用函数负责清空堆栈。如果调用方 (LabVIEW) 和被调用的DLL 函数不使用相同的调用规范,那会出现:要么它们都将数据移出堆栈或者它们都不清空堆栈。任意一种情况会在被调用函数返回的时候导致 LabVIEW崩溃。调用规范在
调用函数节点
窗口的右下角设置,参见下图
确认您连接了调用函数节点的所有输入输出
如果您不连接输入,DLL函数会覆盖没有被分配的内存。如果您不连接输出,LabVIEW假定DLL函数不需要输入端传入的已分配内存空间,并把这些空间用于其他用途。然后,DLL函数会覆盖被保留的LabVIEW内存空间,导致LabVIEW崩溃。
确认DLL函数没有覆盖LabVIEW内存
许多DLL函数需要使用由指针或者值传递的被分配的内存, 写入这些内存并返回。如果没有分配足够的内存空间或者DLL写入了比分配的大小更多的数据,DLL会覆盖保留的LabVIEW内存空间并且导致LabVIEW崩溃。比如说,考虑如下函数:
double *Waveform (double *waveform, uInt32 size);
在这个例子中,合适的分配内存的方法是用合适的维数大小参数初始化数组,而不是传递一个空的数组。下图列举了一个合适的方法。
确认LabVIEW使用了正确的数据类型像函数传递参数
在LabVIEW中使用不正确的参数数据类型(值,参考,句柄,等)调用DLL函数会导致函数意外的指向不正确的内存位置,从而导致数据错误,或者甚至导致LabVIEW或者Windows的崩溃。
如果您在LabVIEW中生成了DLL并且您想要显示DLL VI的前面板,您必须遵照两个必要条件。
-
调用函数节点必须被设置,使调用DLL可以在任何线程运行。这通过更改
线程
单选按钮从
在UI线程中运行
至
在任何线程中运行
。
-
调用的VI不能在用户界面线程中运行。这可以通过This can be checked by selecting从下拉菜单中选择
文件»VI 属性
,在 类别列表中选择
执行
,确认首选执行系统是标准,仪器I/O,数据采集,其他1或者其他2。不能选择与调用方相同选项,因为这样的话父VI可能运行在用户界面线程下。
如果需要完整的关于在LabVIEW 7.1或更早版本上使用其他编程语言的文档,请参考
Using External Code in LabVIEW
手册 (下文附有链接)。在LabVIEW 8.0或者以后的版本上,参考
LabVIEW
帮助中内容列表,
基础»调用以文本编程语言编写的代码
(下文附有链接)查找更多的信息。
LabVIEW 直到关闭时才崩溃
最可能的问题是被调用的DLL函数破坏了内存空间。如果您向DLL传递数组和字符串,DLL函数不能动态更改数组大小。写入超过数组或字符串最后一个元素可能会破坏内存,并且这个问题可能只有在LabVIEW被关闭后才会显现出来。
函数可能自己The function call itself does something illegal
如果函数企图做一些不合法的操作,它也会导致LabVIEW崩溃。如果您不是函数的编写者,联系编写函数的程序员。