- •Worldwide Technical Support and Product Information
- •National Instruments Corporate Headquarters
- •Worldwide Offices
- •Important Information
- •Warranty
- •Copyright
- •Trademarks
- •WARNING REGARDING USE OF NATIONAL INSTRUMENTS PRODUCTS
- •Contents
- •About This Manual
- •Conventions
- •Related Documentation
- •Calling Code in Various Platforms
- •Characteristics of the Two Calling Approaches
- •Details of Call Library Function
- •Details of a CIN
- •Calling Shared Libraries
- •Figure 2-1. Call Library Function Dialog Box
- •Calling Conventions (Windows)
- •Parameters
- •Calling Functions That Expect Other Data Types
- •Building a Shared Library (DLL)
- •Task 1: Build the Function Prototype in LabVIEW
- •Task 2: Complete the .c File
- •Required Libraries
- •Task 3: Build a Library Project in an External IDE
- •Figure 2-2. Creating a Project in Visual C++
- •Figure 2-3. Setting the Use run-time library control, Microsoft Visual C++
- •Gnu C or C++ Compilers on Solaris, Linux, or HP-UX
- •Metrowerks CodeWarrior on Power Macintosh
- •Calling External APIs
- •Common Pitfalls with the Call Library Function
- •Incorrect Function Name
- •Data Types
- •Constants
- •Calling Conventions
- •Example 1: Call a Shared Library that You Built
- •Configuration of Call Library Function
- •Create Front Panel
- •Create the Block Diagram
- •Example 2: Call a Hardware Driver API
- •Figure 2-4. VI That Calls Hardware
- •Example 3: Call the Win32 API
- •Table 2-1. Mapping Win32 Data Types to Standard C Data Types
- •Table 2-2. Mapping Win32 Data Types to LabVIEW Data Types
- •Constants
- •Table 2-3. Selected Constants for MessageBox
- •Figure 2-5. Combining Function Constants in LabVIEW
- •Determining the Proper Library and Function Name
- •Unicode Versions and ANSI Versions of Functions
- •Configuring a Call to the Win32 API
- •Figure 2-6. Configuring Call Library Function to call the Win32 API
- •Figure 2-7. Block Diagram for a Call to the Win32 API
- •Figure 2-8. Running a LabVIEW Call to the Win32 API
- •Additional Examples of LabVIEW Calls to DLLs
- •Debugging DLLs and Calls to DLLs
- •Troubleshooting the Call Library Function
- •Troubleshooting your DLL
- •Troubleshooting Checklist
- •Module Definition Files
- •Array and String Options
- •Arrays of Numeric Data
- •String Data
- •Figure 2-9. The LabVIEW String Format
- •Figure 2-10. The Pascal String Format
- •Figure 2-11. The C String Format
- •Array and String Tip
- •Supported Languages
- •Macintosh
- •Microsoft Windows
- •Solaris, Linux, and HP-UX
- •Resolving Multithreading Issues
- •Making LabVIEW Recognize a CIN as Thread Safe
- •Using C Code that is Thread Safe
- •Creating a CIN
- •Step 1. Set Up Input and Output Terminals for a CIN
- •Input-Output Terminals
- •Output-Only Terminals
- •Step 2. Wire the Inputs and Outputs to the CIN
- •Step 3. Create a .c File
- •Step 4. Compile the CIN Source Code
- •Compile on Macintosh
- •Microsoft Windows
- •Solaris 2.x
- •HP-UX and Linux
- •gcc Compiler
- •Step 5. Load the CIN Object Code
- •LabVIEW Manager Routines
- •Pointers as Parameters
- •Debugging External Code
- •DbgPrintf
- •Windows
- •UNIX
- •Passing Parameters
- •Parameters in the CIN .c File
- •Passing Fixed-Size Data to CINs
- •Scalar Numerics
- •Scalar Booleans
- •Refnums
- •Clusters of Scalars
- •Return Value for CIN Routines
- •Examples with Scalars
- •Creating a CIN That Multiplies Two Numbers
- •Passing Variably Sized Data to CINs
- •Alignment Considerations
- •Arrays and Strings
- •Paths
- •Clusters Containing Variably Sized Data
- •Resizing Arrays and Strings
- •SetCINArraySize
- •NumericArrayResize
- •Examples with Variably Sized Data
- •Concatenating Two Strings
- •Working with Clusters
- •Manager Overview
- •Basic Data Types
- •Scalar
- •char
- •Dynamic
- •Memory-Related
- •Constants
- •Memory Manager
- •Memory Allocation
- •Memory Zones
- •Using Pointers and Handles
- •File Manager
- •Identifying Files and Directories
- •Path Specifications
- •File Descriptors
- •File Refnums
- •Support Manager
- •CIN Routines
- •Data Spaces and Code Resources
- •One Reference to the CIN in a Single VI
- •Loading a VI
- •Unloading a VI
- •Loading a New Resource into the CIN
- •Compiling a VI
- •Running a VI
- •Saving a VI
- •Aborting a VI
- •Multiple References to the Same CIN in a Single VI
- •Multiple References to the Same CIN in Different VIs
- •Single-Threaded Operating Systems
- •Multithreaded Operating Systems
- •Code Globals and CIN Data Space Globals
- •Examples
- •Memory Manager Functions
- •Support Manager Functions
- •Mathematical Operations
- •ASCIITime
- •AZCheckHandle/DSCheckHandle
- •AZCheckPtr/DSCheckPtr
- •AZDisposeHandle/DSDisposeHandle
- •AZDisposePtr/DSDisposePtr
- •AZGetHandleSize/DSGetHandleSize
- •AZHandAndHand/DSHandAndHand
- •AZHandToHand/DSHandToHand
- •AZHeapCheck/DSHeapCheck
- •AZHLock
- •AZHNoPurge
- •AZHPurge
- •AZHUnlock
- •AZMaxMem/DSMaxMem
- •AZMemStats/DSMemStats
- •AZNewHandle/DSNewHandle
- •AZNewHClr/DSNewHClr
- •AZNewPClr/DSNewPClr
- •AZNewPtr/DSNewPtr
- •AZPtrAndHand/DSPtrAndHand
- •AZPtrToHand/DSPtrToHand
- •AZPtrToXHand/DSPtrToXHand
- •AZRecoverHandle/DSRecoverHandle
- •AZSetHandleSize/DSSetHandleSize
- •AZSetHSzClr/DSSetHSzClr
- •BinSearch
- •BlockCmp
- •Cat4Chrs
- •ClearMem
- •CPStrBuf
- •CPStrCmp
- •CPStrIndex
- •CPStrInsert
- •CPStrLen
- •CPStrRemove
- •CPStrReplace
- •CPStrSize
- •CToPStr
- •DateCString
- •DateToSecs
- •FAddPath
- •FAppendName
- •FAppPath
- •FArrToPath
- •FCopy
- •FCreate
- •FCreateAlways
- •FDepth
- •FDirName
- •FDisposePath
- •FDisposeRefNum
- •FEmptyPath
- •FExists
- •FFlattenPath
- •FFlush
- •FGetAccessRights
- •FGetDefGroup
- •FGetEOF
- •FGetInfo
- •FGetPathType
- •FGetVolInfo
- •FileNameCmp
- •FileNameIndCmp
- •FileNameNCmp
- •FIsAPath
- •FIsAPathOfType
- •FIsAPathOrNotAPath
- •FIsARefNum
- •FIsEmptyPath
- •FListDir
- •FLockOrUnlockRange
- •FMakePath
- •FMClose
- •FMOpen
- •FMove
- •FMRead
- •FMSeek
- •FMTell
- •FMWrite
- •FName
- •FNamePtr
- •FNewDir
- •FNewRefNum
- •FNotAPath
- •FPathCmp
- •FPathCpy
- •FPathToArr
- •FPathToAZString
- •FPathToDSString
- •FPathToPath
- •FRefNumToFD
- •FRefNumToPath
- •FRelPath
- •FRemove
- •FSetAccessRights
- •FSetEOF
- •FSetInfo
- •FSetPathType
- •FStrFitsPat
- •FStringToPath
- •FTextToPath
- •FUnFlattenPath
- •FVolName
- •GetALong
- •HexChar
- •HiByte
- •HiNibble
- •IsAlpha
- •IsDigit
- •IsLower
- •IsUpper
- •LoByte
- •Long
- •LoNibble
- •LStrBuf
- •LStrCmp
- •LStrLen
- •LToPStr
- •MilliSecs
- •MoveBlock
- •NumericArrayResize
- •Offset
- •PPStrCaseCmp
- •PPStrCmp
- •Printf
- •PStrBuf
- •PStrCaseCmp
- •PStrCat
- •PStrCmp
- •PStrCpy
- •PStrLen
- •PStrNCpy
- •PToCStr
- •PToLStr
- •QSort
- •RandomGen
- •SecsToDate
- •SetALong
- •SetCINArraySize
- •StrCat
- •StrCmp
- •StrCpy
- •StrLen
- •StrNCaseCmp
- •StrNCmp
- •StrNCpy
- •SwapBlock
- •TimeCString
- •TimeInSecs
- •ToLower
- •ToUpper
- •Unused
- •Word
- •Glossary
Chapter 4 Programming Issues for CINs
Examples with Variably Sized Data
The following examples describe how to create CINs that work with variably sized data types. Refer to Chapter 3, CINs, for more information about creating CINs.
Concatenating Two Strings
To create a CIN that concatenates two strings and use input-output terminals by passing the first string as an input-output parameter to the CIN, complete the following steps. The top right terminal of the CIN returns the result of the concatenation. This example shows only the diagram and the code.
1.To create the CIN, follow the instructions in the Creating a CIN section in Chapter 3, CINs.
The diagram for this CIN is shown in the following illustration.
2.Save the VI as lstrcat.vi.
3.Create a .c file for the CIN and name it lstrcat.c. LabVIEW creates the following .c file.
/*
* CIN source file */
#include "extcode.h"
CIN MgErr CINRun(
LStrHandle var1,
LStrHandle var2);
CIN MgErr CINRun(
LStrHandle var1,
LStrHandle var2) {
/* ENTER YOUR CODE HERE */
return noErr;
}
Using External Code in LabVIEW |
4-14 |
www.ni.com |
Chapter 4 Programming Issues for CINs
4.Fill in the CINRun function, as follows:
CIN MgErr CINRun( LStrHandle strh1, LStrHandle strh2) {
int32 size1, size2, newSize; MgErr err;
size1 = LStrLen(*strh1); size2 = LStrLen(*strh2); newSize = size1 + size2;
if(err = NumericArrayResize(uB, 1L, (UHandle*)&strh1, newSize))
goto out;
/* append the data from the second string to first string */
MoveBlock(LStrBuf(*strh2), LStrBuf(*strh1)+size1, size2);
/* update the dimension (length) of the first string */
LStrLen(*strh1) = newSize; out:
return err;
}
In this example, CINRun is the only routine that performs substantial operations. CINRun concatenates the contents of strh2 to the end of strh1, with the resulting string stored in strh1.
5.Before performing the concatenation, NumericArrayResize resizes strh1 to hold the additional data.
If NumericArrayResize fails, it returns a non-zero value of type MgErr. In this case, NumericArrayResize could fail if LabVIEW does not have enough memory to resize the string. Returning the error code gives LabVIEW a chance to handle the error. If CINRun reports an error, LabVIEW aborts the calling VIs. Aborting the VIs might free up enough memory so LabVIEW can continue running.
After resizing the string handle, MoveBlock copies the second string to the end of the first string. MoveBlock is a support manager routine that moves blocks of data. Finally, this example sets the size of the first string to the length of the concatenated string.
© National Instruments Corporation |
4-15 |
Using External Code in LabVIEW |
Chapter 4 Programming Issues for CINs
Computing the Cross Product of Two
Two-Dimensional Arrays
To create a CIN that accepts two two-dimensional arrays and then computes the cross product of the arrays, complete the following steps. The CIN returns the cross product in a third parameter and a Boolean value as a fourth parameter. This Boolean parameter is TRUE if the number of columns in the first matrix is not equal to the number of rows in the second matrix. This example shows only the front panel, block diagram, and source code.
1.To create the CIN, follow the instructions in the Creating a CIN section in Chapter 3, CINs.
The front panel for this VI is shown in the following illustration.
The block diagram for this VI is shown in the following illustration.
2.Save the VI as cross.vi.
3.Save the .c file for the CIN as cross.c. Following is the source code for cross.c with the CINRun routine added.
/*
* CIN source file */
#include "extcode.h"
Using External Code in LabVIEW |
4-16 |
www.ni.com |
Chapter 4 Programming Issues for CINs
#define ParamNumber 2
/* The return parameter is parameter 2 */
#define NumDimensions 2
/* 2D Array */
/*
* typedefs */
typedef struct {
int32 dimSizes[2]; float64 arg1[1]; } TD1;
typedef TD1 **TD1Hdl;
CIN MgErr CINRun(TD1Hdl A, TD1Hdl B, TD1Hdl AxB, LVBoolean *error);
CIN MgErr CINRun(TD1Hdl A, TD1Hdl B, TD1Hdl AxB, LVBoolean *error) {
int32 |
i,j,k,l; |
int32 |
rows, cols; |
float64 |
*aElmtp, *bElmtp, *resultElmtp; |
MgErr |
err=noErr; |
int32 |
newNumElmts; |
if ((k = (*ah)–>dimSizes[1]) != (*bh)–>dimSizes[0]) {
*error = LVTRUE; goto out;
}
*error = LVFALSE;
rows = (*ah)–>dimSizes[0];
/* number of rows in a and result */ cols = (*bh)–>dimSizes[1];
/* number of cols in b and result */ newNumElmts = rows * cols;
if (err = SetCINArraySize((UHandle)AxB, ParamNumber, newNumElmts))
goto out; (*resulth)–>dimSizes[0] = rows; (*resulth)–>dimSizes[1] = cols; aElmtp = (*ah)–>arg1;
bElmtp = (*bh)–>arg1; resultElmtp = (*resulth)–>arg1; for (i=0; i<rows; i++)
for (j=0; j<cols; j++) { *resultElmtp = 0; for (l=0; l<k; l++)
*resultElmtp += aElmtp[i*k + l] *
© National Instruments Corporation |
4-17 |
Using External Code in LabVIEW |