1. Why?
第三方提供的实际项目经常使用DLL(动态链接库)调用他人封装的函数完成项目任务,但有时会遇到一些指针参考 数,如 int * p; int ** dp; 相信对有些人来说,指针还是比较头疼的 (包括我自己>_<…),那如何在LabVIEW正确使用它们呢?最开始的我 也是模棱两可,凑合着用,忍受偶尔的内存错误,不能顺利打包 exe尴尬,所以通过项目的应用深入探索相关内容,就有了这个总结。
2. What?
本总结主要解决以下问题:
有关dll使用中级指针参数;DLL使用中二级指针参数;使用GetValueByPointer.xnode导致程序包装exe异常运行问题;
3. How?
为了解释方便,我用C封了几个函数,输出了一个111.dll文件用于测 函数的原型和定义如下图所示:
1. 一级指针
一级指针比较容易理解,就是内存中的地址,只是 应注意其数据类型,配置应与函数原型声明中的参数类型一致 一级指针在labview中的Call Library Function Node中还是得到了很好的 支持。以TestFunc3函数为例。
放置在程序框图面板中Call Library Funtion Node.vi , 双击打开配置面板:
1. 选择DLL所在的路径
2. 选择要调用的函数名称
3. 选择调用协议 (这里选用C);
进入参数配置面板,函数声明中有一个形参,即unsigned char * 类型,在左侧添加参数,然后Type选择数组类型(数组名称即第一地址), 然后数组存储的数据类型(unsigned char对应这里Unsigned 8bit Integer),这是一维数组,默认1不变,然后选择数组格式 Array Data Pointer,并将开放的最小内存大小分配到10,此时在 下面可以看到函数原型已经配置成DLL同样,基本上问题不大。
结果与预期相同。
如果不分配内存大小,就无法得到正确的结果,甚至会报告错误。 改为“<NONE>操作错误。
除了在配置面板中指定内存大小外,还可以在程序框图中初始化 一个指定长度的数组来分配大小,显然更灵活,如下图所示。
2. 二级指针
即指针指针,相当于二重地址,简单理解如下图所示,&A表示A在内 存储的地址,&B在内存中表示B的地址。
内存开辟了存储字符串的空间A“Hello LabVIEW!”,B是个一级指 通过针,存储A的地址,通过*(&A)可以分析字符串A,C存放着B的 地址,通过二次分析*(*(&B))还可获得字符串A。
接下来看看怎么在LabVIEW该参数类型在中区配置,LabVIEW二级指针类型不能直接配置,但我们可以通过一级指针获取实际数据的地址 (&A),然后通过分析地址获取相应的数据。
以TestFunc2函数为例。
加入形参cp,类型选Numeric,选择数据类型Signed 32-bit Integer, 以指针的形式输入。
假如以上理解的例子,通过这种配置,cp其实保存的是B 值,即变量A的地址&A,我们真正想要的数据字符串Hello LabVIEW!”, 地址分析还有一步之遥。
这时候就该GetValueByPointer在这条路径下可以找到这个工具,以 2012版本为例(D:\\Program Files (x86)\\National Instruments\\LabVIEW 2012\\vi.lib\\Utility\\importsl\\GetValueByPointer)
引入指针参数,然后指定数据类型,这是一个字符串,可以得到正 结果确实如下图所示。
通过GetValueByPointer分析指针很方便,使用也很简单。您可以根据实际数据类型进行配置。
对指针的分析,LabVIEW它还提供间接函数,MoveBlock函数, 两者的区别之一是:
MoveBlock:任何数据类型都可以处理,级别低,控制多;
GetValueByPointer:使用简单,适应大多数数据类型,不能处理一些复杂类型;
从目前查看的数据来推测,MoveBlock函数应包装到LabVIEW中静态 调用方法如下:
打开调用库函数节点,在路径中输入LabVIEW”;
此时函数名列表将更新许多函数名,其中包括MoveBlock;
参考以下配置:
我这里配置的adress传入方式是Value,并不是Pointer to Value, 原因就是通过直接介绍的TestFunc2的配置,返回的已经是一个Pointer了,所以这里选择值传入。然后指定目标数据类型和大小,运行变可以获取正确的结 果“Hellow LabVIEW!”.
3. 打包exe异常
这里打包有问题的情况主要是使用GetValueByPointer,正常打包完成后, 运行会发现不报错,但是无法正确得到期望的结果,或者出现如下图的错误。
出现这些异常的原因就是GetValueByPointer.xonde根本没有正确执行,因 为它调用了lvimptsl.dll中封装的GetValueByPointer函数,所以在打包的时 候,我们要把lvimptsl.dll包含进去。
把lvimptsl.dll包含到项目中;
打包的时候,在Destinations中新建一个resource文件夹,然后始终 包含;
在Source File Settings中,把它添加到支持路径resource中;
这样打包之后,就可以正常运行了。
在摸索的过程中,参考很多大牛前辈的经验总结,十分感谢。以上内容,如有不对之处还请斧正,感激不尽。
(以上内容均为技成原创,作者:郑定瑞,未经授权不得转载,违者必究!)
往期优秀文章回顾:
总结无数电工忽视的49个技术习惯误区,别拿生命“开玩笑”
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至827202335@qq.com 举报,一经查实,本站将立刻删除。文章链接:https://www.eztwang.com/dongtai/64199.html