LabVIEW调用C/C++ DLLs

简介: LabVIEW调用C/C++ DLLs

LabVIEW调用C/C++ DLLs


什么是DLL封装,什么时候需要使用DLL封装?


解决方案


所谓封装就是指为另一种软件提供兼容性接口的程序。由于第三方DLL的开发设计通常是为了从C语言(或者其它类似的底层语言)中调用,而不从是LabVIEW中调用,因此当使用LabVIEW进行应用程序开发时,往往会用到封装。例如,有的DLL会返回指针或者其它复杂的数据结构,而这在LabVIEW中却无法很容易的实现。


编写一个DLL封装,可以类比在C语言环境下,按照该DLL原始开发者设计的调用DLL方式,来编写一个完全独立的程序。反过来,这个封装程序也是专门针对在LabVIEW中调用DLL所设计的。也就是说,这个新的用C编写的“封装” 程序将原来的C程序(DLL)封装起来,形成一个接口层。使用封装的好处在于,不再需要使用原来的DLL的源代码,也不需要对这些源代码进行任何改动。

Calling C/C++ DLLs ContainingSimple and Complex Datatypes from LabVIEW


Overview


LabVIEWdevelopers often have to call C/C++ DLLs from LabVIEW and because of thedifferences between LabVIEW and C/C++ datatypes, passing and receiving datafrom these DLLs can be intimidating at first.


This exampleseeks to show developers how to pass and receive different types of dataranging from simple datatypes like numerics (int, float, double, etc), arraysand strings to more complex data types like pointers, struct (cluster), arraysof structs, and even arrays of structs that have arrays of structs in them.


In addition,this example seeks to show developers the different ways to pass and receivedata in LabVIEW with a DLL – when functions pass data by value, return datausing a return statement, or return data using pass by reference.


This examplecovers the following use cases:

DataType

Call Type

 

1. Numeric (Integer)

a) Returning a value (return statement)

2. Array of Numerics

b) Returning a pointer (return statement)

3. Strings

c) Passing a parameter (Pass by value)

4. 2 Dimensional Array

d) Returning values by reference (pass by ref)

5. Simple Struct (with basic datatypes)

6. Complex Struct (with structs & arrays)

Attached Files


LabVIEWWrapper.zip: LabVIEW Library (.lvlib)     containing examples on how to call each individual function.


PassingDataSampleDLL.zip: Source code for the ANSI C     DLL as well as the compiled DLL. Written in CVI, but tested to compile in     Visual Studio as well.


CTestApplication.zip: Examples of calling the C DLL     from ANSI C. Written in Visual Studio.


Example Hierarchy


The majority ofVIs in the example were automatically generated using the Import Shared Library Wizard. The wizarddoes not cover all cases, and could not generate VI wrappers for somefunctions, and some VI wrappers were incomplete. However, it gives us a reallygood starting point for calling our DLL.


For an exampleon using the Import Shared Library Wizard, refer to:

Tutorial: Creating Wrapper VIs for C/C++ DLL functionsusing the Import Shared Library Wizard


For anexplanation on what the Import Shared Library Wizard missed, refer to thesection titled Caveats with the Import Shared Library Wizard.


The VIs in theexample are arranged in the following virtual folders in the library:


Import Shared Library Wizard Generated VIs: These are the     auto-generated VIs that were the output of the Import Shared Library     Wizard


Dereferencing Pointers: VIs that assist     with dereferencing pointers. They use either MoveBlock or     GetValueByPointer. See:

Dereferencing Pointers from C/C++ DLLs in LabVIEW


Custom Controls For Structs: Strict Typedef     controls that represent the struct datatypes in the DLL


Completed, Corrected and Added VIs: Additional VIs that     were added in order to work around the caveats encountered using the     Import Shared Library Wizard


Caveats with the Import SharedLibrary Wizard


The followingcases were not completely handled by the Import Shared Library Wizard:


VI Not Generated


In the followingcase, VIs were not generated at all:


When a function returns anything other than a     numeric, string or void. Pointers are fine because they are treated as     numerics.

    In these cases, the data should be treated as a pointer and the data type     in LabVIEW for the return value should be set as Unsigned Pointer-Sized     Integer


In the examplelvlib, these VIs were manually created and given the suffix “Added” to thename.


Incomplete VIs


In the followingcases, the VIs that were generated were incomplete in some fashion:


When a function returned a pointer and the pointer     wasn’t automatically dereferenced.

    In these cases, the pointer needs to be dereferenced using either     MoveBlock or GetValueByPointer. See:

Dereferencing Pointers from C/C++ DLLs in LabVIEW


In the examplelvlib, these VIs completed in a new VI that has the suffix “Complete” in thename.


Incorrect VIs


In the followingcases, the VIs that were generated had some incorrect behavior:


When a function returned a pointer to a pointer     (strings and 2D Arrays)

    These must be dereferenced twice.


When a function took a struct (cluster) with an     array/string in it

    The individual elements should be dereferenced individually.


In the examplelvlib, these VIs were corrected in a new VI and given the suffix “Corrected” tothe name.


List of Functions and VIs (byData Type and Call Type)


The following isa list of functions exposed by the C DLL as well as the VI that shows how toproperly call the particular function.


1.     Numeric (Integer)  


a.     Returning a value (return statement)

Function: int ReturningAValue_Integer (void);

VI: Returning A ValueInteger.vi

Auto Generated VI Status: Working    


b.     Returning a pointer (return statement)

Function: int*ReturningAValue_PointerToInteger (void);

VI: Returning A Value Pointer To Integer Complete.vi

Auto Generated VI Status: Incomplete    


c.     Passing a parameter (Pass by value)

Function: int PassingParameters_Integer(int x, int y);

VI: Passing Parameters Integer.vi

Auto Generated VI Status: Working    


d.     Returning values by reference (pass by ref)

Function: voidReturningValuesByReference_Integer (int x, int y, int *sum);

VI: Returning ValuesBy Reference Integer.vi

Auto Generated VI Status: Working    


2.     Array of Numerics  


a.     Returning a value (return statement)

Function: int*ReturningAValue_ArrayOfIntegers (int length);

VI: Returning A ValueArray Of Integers Complete.vi

Auto Generated VI Status: Incomplete    


b.     Returning a pointer (return statement)

Function: N/A (arrays variables are already pointers)

VI: N/A

Auto Generated VI Status: N/A    


c.     Passing a parameter (Pass by value)

Function: intPassingParamters_ArrayOfIntegers (int x[], int length);

VI: Passing ParamtersArray Of Integers.vi

Auto Generated VI Status: Working    


d.     Returning values by reference (pass by ref)

Function: void ReturningValuesByReference_ArrayOfIntegers (int *x, int length,int **newArray, int *newLength);

VI: Returning ValuesBy Reference Array Of Integers Complete.vi

Auto Generated VI Status: Incomplete    


3.     Strings  


a.     Returning a   value (return statement)

Function: char*ReturningAValue_String (void);

VI: Returning A ValueString.vi

Auto Generated VI Status: Working    


b.     Returning a pointer (return statement)

Function: N/A (arrays variables are already pointers)

VI:N/A

Auto Generated VI Status: N/A    


c.     Passing a parameter (Pass by value)

Function: intPassingParamters_String (char *str);

VI: Passing ParamtersString.vi

Auto Generated VI Status: Working    


d.     Returning values by reference (pass by ref)

Function: voidReturningValuesByReference_String (char *str, char **newString);

VI: Returning ValuesBy Reference String Corrected.vi

Auto Generated VI Status: Incorrect    


4.     2 Dimensional Array  


a.     ReturningAValue_2DArrayOfIntegers

Function: int**ReturningAValue_2DArrayOfIntegers (int rows, int cols);

VI: Returning A Value2D Array Of Integers Complete.vi

Auto Generated VI Status: Incomplete    


b.     Returning a pointer (return statement)

Function: N/A (arrays variables are already pointers)

VI: N/A

Auto Generated VI Status: N/A    


c.     Passing a parameter (Pass by value)

Function: intPassingParamters_2DArrayOfIntegers (int *x, int rows, int cols);

VI: Passing Paramters2D Array Of Integers Corrected.vi

Auto Generated VI Status: Incorrect    


d.     Returning values by reference (pass by ref)

Function: voidReturningValuesByReference_2DArrayOfIntegers (int rows, int cols, int***newArray);

VI: Returning ValuesBy Reference 2D Array Of Integers Complete.vi

Auto Generated VI Status: Incomplete    


5.     Simple Struct (with basic datatypes)  


a.     Returning a   value (return statement)

Function: structsimpleStructCircle ReturningAValue_SimpleStruct(void);

VI: Returning A ValueSimple Struct Added.vi

Auto Geerated VI Status: Not Generated    


b.     Returning a pointer (return statement)

Function: structsimpleStructCircle* ReturningAValue_PointerToSimpleStruct(void);

VI: Returning A ValuePointer To Simple Struct Added.vi

Auto Generated VI Status: Not Generated    


c.     Passing a parameter (Pass by value)

Function: floatPassingParamters_SimpleStruct (struct simpleStructCircle circle);

VI: Passing ParamtersSimple Struct.vi

Auto Generated VI Status: Working    


d.     Returning values by reference (pass by ref)

Function: voidReturningValuesByReference_SimpleStruct (struct simpleStructCircle circle,struct simpleStructCircle *largerCircle);

VI: Returning ValuesBy Reference Simple Struct.vi

Auto Generated VI Status: Working    


e.     Returning array of struct

Function: voidReturningValuesByReference_ArrayOfSimpleStruct (struct simpleStructCircle**circleArray, int length);

VI: Returning ValuesBy Reference Array Of Simple Struct Complete.vi

Auto Generated VI Status: Incomplete  


6.     Complex Struct (with structs and arrays)  


a.     Returning a   value (return statement)

Function: structcomplexStructPolygon ReturningAValue_ComplexStruct (void);

VI: Returning A ValueComplex Struct Added.vi

Auto Generated VI Status: Not Generated    


b.     Returning a pointer (return statement)

Function: structcomplexStructPolygon* ReturningAValue_PointerToComplexStruct (void);

VI: Returning A ValuePointer To Complex Struct Added.vi

Auto Generated VI Status: Not Generated    


c.     Passing a parameter (Pass by value)

Function: intPassingParamters_ComplexStruct (struct complexStructPolygon triangle);

VI: Passing ParamtersComplex Struct Corrected.vi

Auto Generated VI Status: Incorrect    


d.     Returning values by reference (pass by ref)

Function: voidReturningValuesByReference_PointerToComplexStruct (struct complexStructPolygon*triangle);

VI: Returning ValuesBy Reference Pointer To Complex Struct Corrected.vi

Auto Generated VI Status: Incorrect    


e.      Returning array of struct

Function: void ReturningValuesByReference_ArrayOfComplexStruct(struct complexStructPolygon **triangles, int length);

VI: Returning ValuesBy Reference Array Of Complex Struct Corrected.vi

Auto Generated VI Status: Incorrect        


需要说明的是,上述的例程和文档,都是可以下载的,双击即可打开,其中压缩文件是可以采用粘贴复制的方式,拷贝到硬盘上。这不是图片,各位小伙伴看到后尝试一下,这个问题就不用加微信咨询了。有关LabVIEW编程、LabVIEW开发等相关项目,可联系们。

相关文章
|
C++ 数据格式
LabVIEW传递接收C/C++DLL指针
LabVIEW传递接收C/C++DLL指针
301 1
|
存储 C++ Python
LabVIEW使用Python MathWorks® MATLAB®软件和C/C++
LabVIEW使用Python MathWorks® MATLAB®软件和C/C++
166 0
Using Microsoft Visual C++ DLLs with C++Builder
摘自《Borland C++BuilderT 6 Developer's Guide》  一书 Using Microsoft Visual C++ DLLs with C++Builder As powerful as C++Builder is, the majority of DLLs d...
1146 0
|
4月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
8天前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
|
8天前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
|
2月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
84 12
|
3月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
72 16
|
3月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
3月前
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。