动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库。
LabVIEW中,一维数组、二维数组、字符串是可以和C/C++中的相应数据类型直接对应起来,因此比较容易实现。那么对于C/C++语言中的结构体,大家也会想到可以和LabVIEW中的簇对应起来,但是在具体的应用中还会涉及到一些细节,需要我们去留意,否则很可能调用不成功,甚至由于非法读写内存导致系统崩溃。另外,在LabVIEW中的返回值只有数值、字符串和指针,因此当DLL中的函数返回值为结构体时该如何处理?当输入参数包含指向函数的指针时该如何处理?
在解决这些问题之前,先推荐四篇文档,有长有短,但是都写得很细致:
1 如何通过调用库函数结点使用DLL——Configuring the Call Library Function Node to call a Simple DLL 链接:decibel.ni/content/docs/DOC-9069
2 如果是简单的数据类型(如数值、数组、字符串、简单结构体),在LabVIEWDLL之间传递或接收指针,LabVIEW能够自动的正确的解析指针——Passing and Receiving Pointers with C/C++ DLLs from LabVIEW 链接:decibel.ni/content/docs/DOC-9080
3 因为LabVIEW隐藏了对内存的管理,没有开放的函数提供对具体内存地址的直接访问,所以当C/C++中返回的是一个指针,并且LabVIEW又不能自动解析这个指针时,该怎么办——Dereferencing Pointers from C/C++ DLLs in LabVIEW 链接:decibel.ni/content/docs/DOC-9091
4 介绍导入共享库工具(Import Shared Library Wizard),当我们拿到一个DLL和它的头文件(.h)时,利用该工具,能够自动生成针对DLL每个函数的子VI,最大的好处是不需要再手动设置输入输出参数并进行类型匹配,当然它有一定的局限性,比如复杂的类型它匹配不了——Creating Wrapper VIs for C/C++ DLL functions using the Import Shared Library Wizard 链接:decibel.ni/content/docs/DOC-9078
5 大家也可以通过这篇文档直入主题,因为它写得很全,包含详细的VIC/C++源代码,并且有一个目录供大家索引,它回答了以下情况的问题:1)数值型2)一维数组 3)字符串 4)二维数组 5)简单结构体 6)复杂结构体。每种情况又包括:返回值、返回指针、传递值、传递指针——Calling C/C++ DLLs Containing Simple and Complex Datatypes from LabVIEW 链接:decibel.ni/content/docs/DOC-9079(看这些VI调用的时候,一定要参考C/C++中的原代码来进一步的理解,原代码在其链接中都提供下载)
但是这篇文档有几处地方运行的时候出现错误,列举如下:
1. 2D Dimensional Array –c. Passing a parameter (Pass by Value) Function
2. Simple Struct – a. Returning a value (return statement) Function
看了以上内容后,大家可以到:当输入参数是结构体指针(包括简单的和复杂的结构体)、当输入参数是结构体(包含简单的和复杂的结构体)的解决办法。但是当输出参数是结构体、函数输入参数包含指向函数的指针,这个时候需要我们在C/C++额外编写一些代码,封装成DLL
Case 1:输出参数是结构体,因为LabVIEW下没有直接对应结构体的返回值,只有指针、数值、字符串。所以需要把该结构体的地址取出来,返回给LabVIEWLabVIEW再对该地址进行解析。这可以通过在C/C++中写一个函数,该函数获取该函数返回值的地址,如下图中的函GetStructAddress(Void),它获取了ReturningAValue_SimpleStruct(Void)返回值的地址,然后将地址Return。(这里ReturningAValue_SimpleStruct(Void)就是一个返回结构体的函数)。
ReturningAValue_SimpleStruct
LabIVEW字符串函数怎么获取下的调用就很简单(关于MoveBlock函数的使用方法,参考Dereferencing Pointers):
ReturningAValue_SimpleStruct
Case 2:主函数ExeFunc的输入参数包含函数指针Func,则主函数需要获取被调用函数Func的入口地址。应该另写一个函数GetFuncAddrGetFuncAddr就用来获取Func的地址,GetFuncAddr将获取的地址传递给原来的DLL函数:
GetFuncAddr()
LabVIEW下的编程:
GetFuncAddr()
Case 3:如果输入参数是二维数组,在C/C++中函数原型如下:
2D_Array
LabVIEW下的编程:
2D_Array
二维数组的配置:
2D_Array Configuration
以上的三个例程的C/C++原代码和VI分别在Return_ClusterCallback2D Array文件夹下。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。