- •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
not need to pass a function number, because GetProcAddress returns the address of the desired function.
This example uses InvokeIndirectFunction to call the desired DLL function, passing the number of the routine that the example calls as the last parameter. With a DLL made by a compiler other than the Watcom C compiler, you don’t need to pass the function number, because GetProcAddress returns the address of the desired function.
Notice that at each stage of calling the DLL, the code checks for errors and returns an error code if it fails.
Notice also that LabVIEW strings are different from C strings. C strings are terminated with a null character. LabVIEW strings are not null-terminated; instead, they begin with a four byte value that indicates the length of the string. Because the DLL expects C strings, this example creates temporary buffers for the C strings using DSNewPtr, and then uses SPrintf to copy the LabVIEW string into the temporary buffers. You might consider modifying the DLL to accept LabVIEW strings instead, because that would require no temporary copies of the strings.
Compiling the CIN
Following is the LabVIEW makefile for this CIN. It assumes that the
.c file is named msgbox.c, the makefile is named msgbox.lvm, and the three pathnames for the directives codeDir, cinToolsDir, and wcDir are set correctly.
name=msgbox
type=CIN
codeDir=c:\labview\examples\cins\dll
cinToolsDir=c:\labview\cintools
wcDir=c:\wc
!include $(cinToolsDir)\generic.mak
The following command line prompt compiles the CIN.
c:> wmake /f msgbox.lvm
LabVIEW Code Interface Reference Manual |
3-22 |
© National Instruments Corporation |
Chapter 3 CIN Advanced Topics
Optimization
To optimize the performance of this CIN call LoadLibrary during the CINLoad routine, and call FreeLibrary during the CINUnload routine. This keeps the overhead of loading and unloading the DLL from affecting your run-time performance. The following code shows the modifications you need to make to CINRun, CINLoad, and CINUnload to implement this optimization.
HANDLE hDLL = NULL;
CIN MgErr CINLoad(RsrcFile rf)
{
hDLL = LoadLibrary("msgbxdll.dll"); return noErr;
}
CIN MgErr CINRun(LStrHandle message,
LStrHandle winTitle, int32 *err)
{ |
|
FARPROC |
addr = NULL; |
HINDIR |
hMessageBox; |
int |
cb; |
char |
*messageCStr = NULL, |
|
*winTitleCStr = NULL; |
MgErr |
cinErr = noErr; |
*err=0;
if (hDLL < HINSTANCE_ERROR) {
*err = 1;/* LoadLibrary failed */ goto out;
}
addr = GetProcAddress(hDLL,"Win386LibEntry"); if (!addr) {
*err = 2;/* GetProcAddress failed */ goto out;
}
hMessageBox = GetIndirectFunctionHandle(
addr,
INDIR_PTR,
INDIR_PTR,
© National Instruments Corporation |
3-23 |
LabVIEW Code Interface Reference Manual |
Chapter 3 CIN Advanced Topics
INDIR_WORD,
INDIR_ENDLIST );
if (!hMessageBox) {
/* GetIndirectFunctionHandle failed */ *err = 3;
goto out;
}
if (!(messageCStr = DSNewPtr(LStrLen(*message)+1))) {
/* mem errs are serious-stop execution */ cinErr=mFullErr;
goto out;
}
if (!(winTitleCStr = DSNewPtr(LStrLen(*winTitle)+1))) {
/* mem errs are serious-stop execution */ cinErr=mFullErr;
goto out;
}
SPrintf(messageCStr, (CStr) "%P", *message);
SPrintf(winTitleCStr, (CStr) "%P", *winTitle);
cb = (WORD)InvokeIndirectFunction( hMessageBox, messageCStr, winTitleCStr,
0x1 );
out:
if (messageCStr) DSDisposePtr(messageCStr);
if (winTitleCStr) DSDisposePtr(winTitleCStr);
return cinErr;
}
CIN MgErr CINUnload(void)
{
LabVIEW Code Interface Reference Manual |
3-24 |
© National Instruments Corporation |
Chapter 3 CIN Advanced Topics
if (hDLL) FreeLibrary(hDLL);
return noErr;
}
© National Instruments Corporation |
3-25 |
LabVIEW Code Interface Reference Manual |
Chapter 3 CIN Advanced Topics
LabVIEW Code Interface Reference Manual |
3-26 |
© National Instruments Corporation |
