- •Important Information
- •Warranty
- •Copyright
- •Trademarks
- •Organization of This Manual
- •Conventions Used in This Manual
- •Related Documentation
- •Customer Communication
- •Classes of External Code
- •Introduction
- •Supported Languages
- •Macintosh
- •Microsoft Windows 3.1
- •Microsoft Windows 95 and Windows NT
- •Solaris
- •Steps for Creating a CIN
- •1. Place the CIN on a Block Diagram
- •2. Add Input and Output Terminals to the CIN
- •Input-Output Terminals
- •Output-Only Terminals
- •3. Wire the Inputs and Outputs to the CIN
- •4. Create .c File
- •Special Macintosh Considerations
- •5. Compile the CIN Source Code
- •Macintosh
- •THINK C for 68K (Versions 5-7)
- •Symantec C++ 8.0 for Power Macintosh
- •Metrowerks CodeWarrior for 68K
- •Metrowerks CodeWarrior for Power Macintosh
- •Microsoft Windows 3.x
- •Watcom C Compiler
- •Microsoft Windows 95 and Windows NT
- •Microsoft SDK C/C++ Compiler
- •Visual C++ for Windows 95 or Windows NT
- •Solaris 1.x
- •Solaris 2.x
- •6. Load the CIN Object Code
- •LabVIEW Manager Routines
- •Online Reference
- •Pointers as Parameters
- •Debugging External Code
- •DbgPrintf
- •Debugging CINs Under Windows 95 and Windows NT
- •Debugging CINs Under Sun or Solaris
- •Debugging CINs Under HP-UX
- •Introduction
- •CIN .c File
- •How LabVIEW Passes Fixed Sized Data to CINs
- •Scalar Numerics
- •Scalar Booleans
- •Refnums
- •Clusters of Scalars
- •Return Value for CIN Routines
- •Examples with Scalars
- •1. Place the CIN on the Block Diagram
- •2. Add Two Input and Output Terminals to the CIN
- •3. Wire the Inputs and Outputs to the CIN
- •4. Create the CIN Source Code
- •5. Compile the CIN Source Code
- •Macintosh
- •THINK C for 68K and Symantec C++
- •Microsoft Windows 3.x
- •Watcom C Compiler
- •Microsoft Windows 95 and Windows NT
- •Microsoft SDK Compiler
- •Microsoft Visual C++ Compiler
- •Solaris 1.x, Solaris 2.x, and HP-UX
- •6. Load the CIN Object Code
- •Comparing Two Numbers, Producing a Boolean Scalar
- •How LabVIEW Passes Variably Sized Data to CINs
- •Alignment Considerations
- •Arrays and Strings
- •Paths (Path)
- •Clusters Containing Variably Sized Data
- •Resizing Arrays and Strings
- •SetCINArraySize
- •NumericArrayResize
- •Examples with Variably Sized Data
- •Concatenating Two Strings
- •Working with Clusters
- •CIN Routines
- •Data Spaces and Code Resources
- •CIN Routines: The Basic Case
- •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
- •Reentrancy
- •Code Globals and CIN Data Space Globals
- •Examples
- •Using Code Globals
- •Using CIN Data Space Globals
- •Calling a Windows 3.1 Dynamic Link Library
- •2. Get the address of the desired function
- •3. Describe the function
- •4. Call the function
- •Calling a 16-Bit DLL
- •1. Load the DLL
- •Example: A CIN that Displays a Dialog Box
- •The Block Diagram
- •The CIN Code
- •Compiling the CIN
- •Optimization
- •Introduction
- •Creating Shared External Subroutines
- •External Subroutine
- •Macintosh
- •THINK C Compiler and CodeWarrior 68K Compiler
- •MPW Compiler
- •Solaris 1.x, Solaris 2.x, and HP-UX
- •Calling Code
- •Macintosh
- •THINK C Compiler
- •CodeWarrior 68K Compiler
- •MPW Compiler
- •Solaris 1.x, Solaris 2.x, and HP-UX
- •Simple Example
- •External Subroutine Example
- •Compiling the External Subroutine
- •Macintosh
- •THINK C Compiler and CodeWarrior 68K Compiler
- •MPW Compiler
- •Microsoft Windows 3.1
- •Watcom C Compiler
- •Microsoft Windows 95 and Windows NT
- •Solaris 1.x, Solaris 2.x, and HP-UX
- •Calling Code
- •Compiling the Calling Code
- •Macintosh
- •THINK C Compiler
- •CodeWarrior 68K Compiler
- •MPW Compiler
- •Microsoft Windows 3.1
- •Watcom C Compiler
- •Microsoft Windows 95 and Windows NT
- •Solaris 1.x, Solaris 2.x, and HP-UX
- •Introduction
- •Basic Data Types
- •Scalar Data Types
- •Booleans
- •Numerics
- •Complex Numbers
- •char Data Type
- •Dynamic Data Types
- •Arrays
- •Strings
- •C-Style Strings (CStr)
- •Pascal-Style Strings (PStr)
- •LabVIEW Strings (LStr)
- •Concatenated Pascal String (CPStr)
- •Paths (Path)
- •Memory-Related Types
- •Constants
- •Memory Manager
- •Memory Allocation
- •Static Memory Allocation
- •Dynamic Memory Allocation: Pointers and Handles
- •Memory Zones
- •Using Pointers and Handles
- •Simple Example
- •Reference to the Memory Manager
- •Memory Manager Data Structures
- •File Manager
- •Introduction
- •Identifying Files and Directories
- •Path Specifications
- •Conventional Path Specifications
- •Empty Path Specifications
- •LabVIEW Path Specification
- •File Descriptors
- •File Refnums
- •Support Manager
- •Allocating and Releasing Handles
- •Allocating and Releasing Pointers
- •Manipulating Properties of Handles
- •AZHLock
- •AZHPurge
- •AZHNoPurge
- •AZHUnlock
- •Memory Utilities
- •ClearMem
- •MoveBlock
- •SwapBlock
- •Handle and Pointer Verification
- •Memory Zone Utilities
- •File Manager Data Structures
- •File/Directory Information Record
- •File Type Record
- •Path Data Type
- •Permissions
- •Volume Information Record
- •File Manager Functions
- •Performing Basic File Operations
- •FCreate
- •FCreateAlways
- •FMClose
- •FMOpen
- •FMRead
- •FMWrite
- •Positioning the Current Position Mark
- •FMSeek
- •FMTell
- •Positioning the End-Of-File Mark
- •FGetEOF
- •FSetEOF
- •Flushing File Data to Disk
- •FFlush
- •FExists
- •FGetAccessRights
- •FGetInfo
- •FGetVolInfo
- •FSetAccessRights
- •FSetInfo
- •Getting Default Access Rights Information
- •FGetDefGroup
- •FListDir
- •FNewDir
- •Copying Files
- •FCopy
- •Moving and Deleting Files and Directories
- •FMove
- •FRemove
- •Locking a File Range
- •FLockOrUnlockRange
- •Matching Filenames with Patterns
- •FStrFitsPat
- •Creating Paths
- •FAddPath
- •FAppendName
- •FAppPath
- •FEmptyPath
- •FMakePath
- •FNotAPath
- •FRelPath
- •Disposing Paths
- •FDisposePath
- •Duplicating Paths
- •FPathCpy
- •FPathToPath
- •Extracting Information from a Path
- •FDepth
- •FDirName
- •FName
- •FNamePtr
- •FVolName
- •FArrToPath
- •FFlattenPath
- •FPathToArr
- •FPathToAZString
- •FPathToDSString
- •FStringToPath
- •FTextToPath
- •FUnFlattenPath
- •Comparing Paths
- •FIsAPath
- •FIsAPathOrNotAPath
- •FIsEmptyPath
- •FPathCmp
- •Determining a Path Type
- •FGetPathType
- •FIsAPathOfType
- •FSetPathType
- •Manipulating File Refnums
- •FDisposeRefNum
- •FIsARefNum
- •FNewRefNum
- •FRefNumToFD
- •FRefNumToPath
- •Byte Manipulation Operations
- •Mathematical Operations
- •For THINK C Users
- •RandomGen
- •String Manipulation
- •BlockCmp
- •CPStrCmp
- •CPStrIndex
- •CPStrInsert
- •CPStrRemove
- •CPStrReplace
- •CPStrSize
- •CToPStr
- •HexChar
- •IsAlpha
- •IsDigit
- •IsLower
- •IsUpper
- •LStrCmp
- •LToPStr
- •PPStrCaseCmp
- •PPStrCmp
- •PStrCaseCmp
- •PStrCat
- •PStrCmp
- •PStrCpy
- •PStrNCpy
- •PToCStr
- •PToLStr
- •StrCat
- •StrCmp
- •StrCpy
- •StrLen
- •StrNCaseCmp
- •StrNCmp
- •StrNCpy
- •ToLower
- •ToUpper
- •Utility Functions
- •BinSearch
- •QSort
- •Time Functions
- •ASCIITime
- •DateCString
- •DateToSecs
- •MilliSecs
- •SecsToDate
- •TimeCString
- •TimeInSecs
- •Microsoft Windows 3.1, Windows 95, and Windows NT
- •Macintosh
- •How do I debug my CIN?
- •Can LabVIEW be used to call a DLL in Windows?
- •Glossary
- •Index
Chapter 3 CIN Advanced Topics
In some cases, you may want globals for each reference to the code resource multiplied by the number of usages of the VI (if the VI is reentrant). For each instance of one of these globals, LabVIEW allocates the CIN data space for the use of the code interface node. Within the CINInit, CINDispose, CINAbort, and CINRun routines you can call the GetDSStorage routine to retrieve the value of the CIN data space for the current instance. You can also call SetDSStorage to set the value of the CIN data space for this instance.
You can use this storage location to store any 4-byte quantity that you want to have for each instance of one of these globals. If you need more than four bytes of global data, you can store a handle or pointer to a structure containing your globals.
The following two lines of code are examples of the exact syntax of these two routines, defined in extcode.h.
int32 GetDSStorage(void);
This routine returns the value of the 4-byte quantity in the CIN data space that LabVIEW allocates for each CIN code resource, or for each use of the surrounding VI (if the VI is reentrant). You should call this routine only from CINInit, CINDispose, CINAbort, or CINRun.
int32 SetDSStorage(int32 newVal);
This routine sets the value of the 4-byte quantity in the CIN data space that LabVIEW allocates for each CIN use of that code resource, or the uses of the surrounding VI, (if the VI is reentrant). It returns the old value of the 4-byte quantity in that CIN data space. You should call this routine only from CINInit, CINDispose, CINAbort, or CINRun.
Examples
The following two examples illustrate the differences between code globals and CIN data space globals. In both examples, the CIN takes a
© National Instruments Corporation |
3-9 |
LabVIEW Code Interface Reference Manual |
Chapter 3 CIN Advanced Topics
number and returns the average of that number and the previous numbers passed to it.
When you design your code, decide whether it is appropriate to use code globals or data space globals. If you use code globals, calling the same code resource from multiple nodes or different reentrant VIs will affect the same set of globals. In the code globals averaging example, the result will indicate the average of all values passed to the CIN.
If you use CIN data space globals, each CIN that calls the same code resource and each VI, if the VI is reentrant, can have its own set of globals. In the CIN data space averaging example, the results would indicate the average of values passed to a specific node for a specific data space.
If you have only one CIN referencing the code resource, and the VI that contains that CIN is not reentrant, it does not matter which method you choose.
Using Code Globals
The following code implements averaging using code globals. Notice that the variables are initialized in CINLoad. If the variables are dynamically created (that is, if they are pointers or handles), you can allocate the memory for the pointer or handle in CINLoad, and deallocate it in CINUnload. You can do this because CINLoad and CINUnload are called only once, regardless of the number of references to the code resources and the number of data spaces. Notice that the UseDefaultCINLoad macro is not used, because this .c file has a CINLoad function.
/*
* CIN source file */
#include "extcode.h"
LabVIEW Code Interface Reference Manual |
3-10 |
© National Instruments Corporation |
Chapter 3 CIN Advanced Topics
float64 gTotal; int32 gNumElements;
/* stubs for advanced CIN functions */
UseDefaultCINInit
UseDefaultCINDispose
UseDefaultCINAbort
UseDefaultCINUnload
UseDefaultCINSave
CIN MgErr CINRun(float64 *new_num, float64 *avg);
CIN MgErr CINRun(float64 *new_num, float64 *avg)
{
gTotal += *new_num; gNumElements++;
*avg = gTotal / gNumElements;
return noErr;
}
CIN MgErr CINLoad(RsrcFile rf)
{
gTotal=0;
gNumElements=0;
return noErr;
}
Using CIN Data Space Globals
The following is an alternative implementation of averaging using CIN data space globals. A handle for the global data is allocated in CINInit, and stored in the CIN data space storage using SetDSStorage. When LabVIEW calls the CINInit, CINDispose, CINAbort, or CINRun routines, it ensures that
GetDSStorage and SetDSStorage will return the 4 byte CIN data space value for that node or CIN data space.
When you want to access that data, use GetDSStorage to retrieve the handle and then dereference the appropriate fields (see the code for
© National Instruments Corporation |
3-11 |
LabVIEW Code Interface Reference Manual |
Chapter 3 CIN Advanced Topics
CINRun in the following example). Finally, in your CINDispose routine you need to dispose of the handle.
/*
* CIN source file */
#include "extcode.h"
/* stubs for advanced CIN functions */
UseDefaultCINAbort
UseDefaultCINLoad
UseDefaultCINUnload
UseDefaultCINSave
typedef struct { |
|
float64 |
total; |
int32 |
numElements; |
} dsGlobalStruct; |
|
CIN MgErr CINInit() { dsGlobalStruct **dsGlobals; MgErr err = noErr;
if (!(dsGlobals = (dsGlobalStruct **) DSNewHandle(sizeof(dsGlobalStruct))))
{
/* if 0, ran out of memory */ err = mFullErr;
goto out;
}
(*dsGlobals)->numElements=0; (*dsGlobals)->total=0;
SetDSStorage((int32) dsGlobals); out:
return noErr;
}
CIN MgErr CINDispose()
LabVIEW Code Interface Reference Manual |
3-12 |
© National Instruments Corporation |
