Integrating LabVIEW Code into Other Programming Languages

Publish Date: Jan 14, 2009 | 28 Ratings | 3.50 out of 5 | Print

Overview

This topic focuses on the ability to turn LabVIEW applications into shared libraries (DLLs), using an example of calling LabVIEW code from the C++ programming language. This document describes the VIs, how to build the VIs into a DLL, and how to call the DLL from C++.

Table of Contents

  1. Introduction
  2. Example
  3. Creating a DLL in LabVIEW
  4. Calling a LabVIEW-Built DLL from C++
  5. Considerations and Recommendations

1. Introduction

Productivity studies have shown the LabVIEW graphical development environment greatly reduces development time and increases productivity. If you have large amounts of legacy code and you want to reuse the code, it is essential that you are able to integrate LabVIEW code with the existing legacy programs.

Recent advances in the LabVIEW environment have made integrating LabVIEW code into other applications as easy as creating DLLs in any development environment. The VI Server makes communicating with LabVIEW code from other languages easier. You can build VIs into shared libraries (DLLs), which greatly increases the ability to integrate LabVIEW into other languages. You also can transform LabVIEW code into a standard interface that allows other programs to execute the LabVIEW code in process, thus greatly increasing the speed of code execution.

Back to Top

2. Example

The example presented in this document illustrates integrating VIs into the C++ programming language. Because LabVIEW is a graphical development environment that provides the best tools for acquiring, analyzing, and presenting data, the LabVIEW code consists of three different VIs: a VI that acquires data, a VI that analyzes the acquired data, and a VI that presents the results. Although the three VIs could be combined into one VI, they are kept separate to illustrate some of the functionality of integrating LabVIEW code using a DLL. Each VI has controls and indicators associated with the connector pane so you can export them using the DLL interface.

The acquisition VI namedAcquireWaveforms.vi, acquires several simulated waveforms from a scope using the Interchangeable Virtual Instrument (IVI) interface. The scope is initialized in the C++ program enabling the VI to accept the scope handle as an input along with acquisition parameters and return the waveforms to the C++ program.

The analysis VI namedAnalyzeWaveforms.vi, determines whether the acquired waveforms meet certain specifications and returns a pass or fail rating for each waveform. The C++ program provides simulated data, the data acquired from the acquisition VI, and pass criteria. The AnalyzeWaveforms.vi calculates the FFT of both the simulated and acquired waveforms and determines the RMS values of the difference. The VI compares these values to the specification to determine whether a waveform passes. The VI returns an array of RMS values and pass/fail Boolean values to the C++ program.

The presentation VI namedPresentData.vi, displays the results of the testing performed in the acquisition VI. A graph displays the different RMS values for each waveform and a table displays whether each waveform passed or failed. The PresentData.vi receives both pieces of data from the C++ program.

See Also:
Integrating LabVIEW Code into Other Programming Languages

Back to Top

3. Creating a DLL in LabVIEW


To create a DLL in LabVIEW, you must have the LabVIEW Application Builder. The LabVIEW Professional Development System includes the Application Builder. If you use the LabVIEW Base Package or Full Development System, you can purchase the Application Builder separately by visiting the National Instruments Web site.

Complete the following steps to create a DLL.
1. Select Tools»Build Application or Shared Library (DLL).
2. On the Target tab of the dialog box, select Shared Library (DLL) from the Build target pull-down menu, as shown in the following example.

Figure 1. Target Tab

3. On the Source Files tab, add each VI as an exported VI, as shown in the following example. Every exported VI corresponds to a new function in the resulting DLL. LabVIEW creates one DLL with several functions. In this example, you add three exported VIs,AcquireWaveforms.vi, AnalyzeWaveforms.vi, and PresentData.vi, which correspond to three functions in the DLL.

Figure 2. Source Files Tab

4. Each time you add an exported VI, you must specify a function prototype. The function prototype associates controls and indicators in the connector pane with parameters in the function. When you define the VI prototype, you can configure various options for each parameter. As you add parameters, LabVIEW builds the function prototype, as shown in the following example. Use this function prototype when you call the function from other programming languages, such as C++. You can obtain the prototype from the dialog box shown in the following example or from the header file created for the DLL.

Figure 3. Define VI Prototype Dialog Box

By default, the front panel of a VI does not appear when you execute its corresponding function. This behavior works well for the acquisition and analysis functions because they perform a task and return data. However, for the presentation VI, it is critical to show the front panel of the VI when you call its function. To configure a VI to show its front panel, you must configure the VI so LabVIEW does not remove its front panel when building the DLL. To do so, click Edit Build Settings on the VI Settings tab, as shown in Figure 4. You also must open the front panel programmatically using the Front Panel Window:Open property, as shown in Figure 5. Place the Property Node before all other code executes to make sure all updates take place after the front panel appears.

Figure 4. VI Settings Tab

 

Figure 5. Property Node with Front Panel Window:Open Property Selected

See Also:
Products & Services: LabVIEW Application Builder

Back to Top

4. Calling a LabVIEW-Built DLL from C++

After you build the DLL in LabVIEW using the Application Builder, you can call the code from other languages. In this example, the other language is C++ and you can load the DLL in two ways. You can statically link the code using the .lib file created during the build process, or you can dynamically load the DLL at run time. This example dynamically loads the DLL so the code is in memory only while the VIs are called. This method provides increased memory management, which often leads to increases in performance.

To dynamically load the DLL, you must define function types and function pointers for all the functions in the DLL. You then load the DLL into memory when necessary using the LoadLibrary function. After loading the DLL, use the GetProcAddress function to obtain the addresses of the functions. After you call all the functions, unload the DLL using the FreeLibrary function.

Back to Top

5. Considerations and Recommendations

National Instruments recommends using simple data structures and keeping data flat when passing it from an external programming language into a LabVIEW-built DLL. In other words, use numbers, strings, 1D arrays, and other data structures that do not require the use of handles to refer to specific blocks of memory. Passing complex data types between applications is often difficult. In LabVIEW, memory management functions allocate memory and create LabVIEW data types. These memory management functions handle the data space sharing to pass complex data types into LabVIEW. The use of memory management functions can lead to problems if more than one instance of the LabVIEW Run-Time Engine is installed on the computer. Incompatible calls might result because the DLL uses the first instance of the Run-Time Engine that it finds, which might not be the correct version needed to run the DLL.

Passing flat data into LabVIEW does not prevent the LabVIEW application from using the data in a more complex manner. You can group various data types into clusters inside the LabVIEW code using the Bundle function. The example described in this document shows that you can pass multidimensional arrays as a 1D array into LabVIEW and reshape them inside LabVIEW using the Reshape Array function. It is necessary only to pass n-1 dimensional parameters for a corresponding n-dimension array.

National Instruments also recommends that if you have more than one LabVIEW-built DLL in any program, that you build them in the same version of LabVIEW. If you use different versions, passing information between the DLLs is more difficult because the only common memory space is the calling language memory space. In contrast, if you build them in the same version, all DLLs use the same instance of the LabVIEW Run-Time Engine, and share a common memory space.

If all DLLs use the same version of the LabVIEW Run-Time Engine and you load the DLLs dynamically, National Instruments recommends you dynamically load the LabVIEW Run-Time Engine before you load any of the LabVIEW-built DLLs by loading the lvrt.dll file. Loading the LabVIEW Run-Time Engine before you load the DLLs reduces overhead by preventing the Run-Time Engine from loading and unloading when the DLLs are loaded and unloaded from memory.

Back to Top

Bookmark & Share


Ratings

Rate this document

Answered Your Question?
Yes No

Submit