CIRMBook
CIRMBook
Manual
Fax-on-Demand Support
512 418 1111
International Offices
Australia 03 9879 5166, Austria 0662 45 79 90 0, Belgium 02 757 00 20, Brazil 011 288 3336,
Canada (Ontario) 905 785 0085, Canada (Québec) 514 694 8521, Denmark 45 76 26 00, Finland 09 725 725 11,
France 01 48 14 24 24, Germany 089 741 31 30, Hong Kong 2645 3186, Israel 03 6120092, Italy 02 413091,
Japan 03 5472 2970, Korea 02 596 7456, Mexico 5 520 2635, Netherlands 0348 433466, Norway 32 84 84 00,
Singapore 2265886, Spain 91 640 0085, Sweden 08 730 49 70, Switzerland 056 200 51 51, Taiwan 02 377 1200,
United Kingdom 01635 523545
Warranty
The media on which you receive National Instruments software are warranted not to fail to execute programming
instructions, due to defects in materials and workmanship, for a period of 90 days from date of shipment, as evidenced
by receipts or other documentation. National Instruments will, at its option, repair or replace software media that do not
execute programming instructions if National Instruments receives notice of such defects during the warranty period.
National Instruments does not warrant that the operation of the software shall be uninterrupted or error free.
A Return Material Authorization (RMA) number must be obtained from the factory and clearly marked on the outside
of the package before any equipment will be accepted for warranty work. National Instruments will pay the shipping costs
of returning to the owner parts which are covered by warranty.
National Instruments believes that the information in this manual is accurate. The document has been carefully reviewed
for technical accuracy. In the event that technical or typographical errors exist, National Instruments reserves the right to
make changes to subsequent editions of this document without prior notice to holders of this edition. The reader should
consult National Instruments if errors are suspected. In no event shall National Instruments be liable for any damages
arising out of or related to this document or the information contained in it.
EXCEPT AS SPECIFIED HEREIN, NATIONAL INSTRUMENTS MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AND
SPECIFICALLY DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. CUSTOMER’S
RIGHT TO RECOVER DAMAGES CAUSED BY FAULT OR NEGLIGENCE ON THE PART OF NATIONAL INSTRUMENTS SHALL BE
LIMITED TO THE AMOUNT THERETOFORE PAID BY THE CUSTOMER. NATIONAL INSTRUMENTS WILL NOT BE LIABLE FOR
DAMAGES RESULTING FROM LOSS OF DATA, PROFITS , USE OF PRODUCTS, OR INCIDENTAL OR CONSEQUENTIAL DAMAGES ,
EVEN IF ADVISED OF THE POSSIBILITY THEREOF . This limitation of the liability of National Instruments will apply
regardless of the form of action, whether in contract or tort, including negligence. Any action against National
Instruments must be brought within one year after the cause of action accrues. National Instruments shall not be liable for
any delay in performance due to causes beyond its reasonable control. The warranty provided herein does not cover
damages, defects, malfunctions, or service failures caused by owner’s failure to follow the National Instruments
installation, operation, or maintenance instructions; owner’s modification of the product; owner’s abuse, misuse, or
negligent acts; and power failure or surges, fire, flood, accident, actions of third parties, or other events outside reasonable
control.
Copyright
Under the copyright laws, this publication may not be reproduced or transmitted in any form, electronic or mechanical,
including photocopying, recording, storing in an information retrieval system, or translating, in whole or in part, without
the prior written consent of National Instruments Corporation.
Trademarks
LabVIEW™, natinst.com™, National Instruments™ are trademarks of National Instruments Corporation.
Product and company names listed are trademarks or trade names of their respective companies.
Chapter 1
CIN Overview
Introduction......................................................................................................................1-1
Classes of External Code...................................................................................1-2
Supported Languages ........................................................................................1-3
Macintosh............................................................................................1-3
Microsoft Windows 3.1.......................................................................1-4
Microsoft Windows 95 and Windows NT ..........................................1-4
Solaris..................................................................................................1-4
HP-UX and Concurrent.......................................................................1-5
Steps for Creating a CIN..................................................................................................1-5
Place the CIN on a Block Diagram ...................................................................1-6
Add Input and Output Terminals to the CIN.....................................................1-6
Input-Output Terminals.......................................................................1-7
Output-Only Terminals .......................................................................1-8
Wire the Inputs and Outputs to the CIN............................................................1-8
Create .c File......................................................................................................1-9
Special Macintosh Considerations ......................................................1-11
Compile the CIN Source Code ..........................................................................1-12
Macintosh............................................................................................1-13
THINK C for 68K (Version 7) .............................................1-13
Symantec C++ 8.0 for Power Macintosh..............................1-16
Metrowerks CodeWarrior for 68K .......................................1-18
Metrowerks CodeWarrior for Power Macintosh ..................1-20
Macintosh Programmer’s Workshop for 68K
and Power Macintosh ........................................................1-22
Microsoft Windows 3.x.......................................................................1-26
Watcom C Compiler .............................................................1-26
Microsoft Windows 95 and Windows NT ..........................................1-28
Visual C++ Command Line..................................................1-28
Visual C++ IDE ....................................................................1-30
Symantec C...........................................................................1-30
Chapter 2
CIN Parameter Passing
Introduction ..................................................................................................................... 2-1
CIN .c File ....................................................................................................................... 2-1
How LabVIEW Passes Fixed Sized Data to CINs .......................................................... 2-2
Scalar Numerics ................................................................................................ 2-2
Scalar Booleans................................................................................................. 2-2
Refnums ............................................................................................................ 2-3
Clusters of Scalars............................................................................................. 2-3
Return Value for CIN Routines....................................................................................... 2-3
Examples with Scalars..................................................................................................... 2-4
Creating a CIN That Multiplies Two Numbers ................................................ 2-4
Comparing Two Numbers, Producing a Boolean Scalar .................................. 2-7
How LabVIEW Passes Variably Sized Data to CINs ..................................................... 2-8
Alignment Considerations................................................................................. 2-9
Arrays and Strings............................................................................................. 2-10
Paths (Path) ....................................................................................................... 2-10
Clusters Containing Variably Sized Data ......................................................... 2-10
Resizing Arrays and Strings ............................................................................................ 2-11
SetCINArraySize............................................................................................................. 2-12
NumericArrayResize ....................................................................................................... 2-13
Examples with Variably Sized Data................................................................................ 2-15
Concatenating Two Strings ............................................................................... 2-15
Computing the Cross Product of Two Two-Dimensional Arrays..................... 2-17
Working with Clusters ...................................................................................... 2-20
Chapter 3
CIN Advanced Topics
CIN Routines ...................................................................................................................3-1
Data Spaces and Code Resources......................................................................3-1
CIN Routines: The Basic Case ..........................................................................3-3
Loading a VI .......................................................................................3-3
Unloading a VI....................................................................................3-4
Loading a New Resource into the CIN ...............................................3-4
Compiling a VI....................................................................................3-4
Running a VI .......................................................................................3-5
Saving a VI..........................................................................................3-5
Aborting a VI ......................................................................................3-5
Multiple References to the Same CIN in a Single VI .......................................3-5
Multiple Reference to the same CIN in different VIs .......................................3-6
Single Threaded Operating Systems ...................................................3-7
Multithreaded Operating Systems.......................................................3-8
Code Globals and CIN Data Space Globals ......................................................3-8
Examples.............................................................................................3-9
Using Code Globals..............................................................3-10
Using CIN Data Space Globals ............................................3-11
Calling a Windows 95 or Windows NT Dynamic Link Library .....................................3-12
Calling a Windows 3.1 Dynamic Link Library ...............................................................3-12
Calling a 16-Bit DLL.........................................................................................3-13
1. Load the DLL..................................................................................3-13
2. Get the address of the desired function ...........................................3-14
3. Describe the function ......................................................................3-14
4. Call the function..............................................................................3-15
Example: A CIN that Displays a Dialog Box....................................................3-15
The DLL..............................................................................................3-15
The CIN Code .....................................................................................3-17
Compiling the CIN..............................................................................3-20
Optimization........................................................................................3-20
Chapter 4
External Subroutines
Introduction......................................................................................................................4-1
Creating Shared External Subroutines .............................................................................4-2
External Subroutines .........................................................................................4-3
Macintosh............................................................................................4-3
Microsoft Windows 3.1, Windows 95, and Windows NT..................4-3
Solaris 1.x, Solaris 2.x, HP-UX, and Concurrent PowerMAX ...........4-4
Chapter 5
Manager Overview
Introduction ..................................................................................................................... 5-1
Basic Data Types............................................................................................................. 5-2
Scalar Data Types ............................................................................................. 5-2
Booleans ............................................................................................. 5-2
Numerics............................................................................................. 5-3
Complex Numbers................................................................ 5-4
char Data Type .................................................................................................. 5-4
Dynamic Data Types......................................................................................... 5-4
Arrays ................................................................................................. 5-4
Strings ................................................................................................. 5-5
C-Style Strings (CStr) .......................................................... 5-5
Pascal-Style Strings (PStr) ................................................... 5-5
LabVIEW Strings (LStr) ...................................................... 5-5
Concatenated Pascal String (CPStr)..................................... 5-6
Paths (Path)......................................................................................... 5-6
Memory-Related Types..................................................................................... 5-6
Constants........................................................................................................... 5-7
Appendix A
CIN Common Questions
Appendix B
Customer Communication
Glossary
Figures
Figure 3-1. Data Storage Spaces for One CIN, Simple Case.....................................3-2
Figure 3-2. Three CINs Referencing the Same Code Resource.................................3-6
Figure 3-3. Three VIs Referencing a Reentrant VI Containing One CIN .................3-7
Tables
Table 1-1. Functions with Parameters Needing Pre-allocated Memory ...................1-35
bold Bold text denotes the names of menus, menu items, parameters, dialog
boxes, dialog box buttons or options, icons, windows, Windows 95 tabs,
or LEDs.
bold italic Bold italic text denotes an activity objective, note, caution, or warning.
monospace Text in this font denotes text or characters that you should literally enter
from the keyboard, sections of code, programming examples, and syntax
examples. This font is also used for the proper names of disk drives, paths,
directories, programs, subprograms, subroutines, device names, functions,
operations, variables, filenames and extensions, and for statements and
comments taken from programs.
monospace italic Italic text in this font denotes that you must enter the appropriate words or
values in the place of these items.
<> Angle brackets enclose the name of a key on the keyboard—for example,
<shift>. Angle brackets containing numbers separated by an ellipsis
represent a range of values associated with a bit or signal name—for
example, DBIO<3..0>.
paths Paths in this manual are denoted using backslashes (\) to separate drive
names, directories, folders, and files.
This icon to the left of bold italicized text denotes a note, which alerts you
to important information.
This icon to the left of bold italicized text denotes a caution, which advises
! you of precautions to take to avoid injury, data loss, or a system crash.
Related Documentation
The following documents contain information that you might find helpful
as you read this manual:
• G Programming Reference Manual
• LabVIEW User Manual
• LabVIEW Function and VI Reference Manual
• LabVIEW Online Reference, available by selecting
Help»Online Reference
Customer Communication
National Instruments wants to receive your comments on our products and
manuals. We are interested in the applications you develop with our
products, and we want to help if you have problems with them. To make it
easy for you to contact us, this manual contains comment and configuration
forms for you to complete. These forms are in Appendix B, Customer
Communication, at the end of this manual.
Introduction
A CIN is a block diagram node associated with a section of source
code written in a conventional programming language. You compile the
source code first and link it to form executable code. LabVIEW calls the
executable code when the node executes, passing input data from the
block diagram to the executable code, and returning data from the
executable code to the block diagram.
The LabVIEW compiler can usually generate code fast enough for most
of your programming tasks. However, you can use CINs for tasks a
conventional language can accomplish more easily, such as tasks that are
time-critical or require a great deal of data manipulation. CINs are also
useful for tasks you cannot perform directly from the diagram, such as
calling system routines for which no corresponding LabVIEW functions
exist. CINs can also link existing code to LabVIEW, although you may
need to modify the code so it uses the correct LabVIEW data types.
When CIN object code executes, it takes control of its execution thread.
If LabVIEW has only a single thread of control, then all of LabVIEW is
stopped until the CIN object code returns. On single-threaded operation
systems such as Macintosh and Windows 3.1, CINs even prevent other
applications from running. In multi-threaded operating systems such as
Windows 95/NT, only the execution thread running the CIN is locked up.
However, if there is only one execution thread, other VIs are prevented
from running.
A CIN appears on the diagram as an icon with input and output terminals.
You associate this node with a section of code you want LabVIEW to call.
When it is time for the node to execute, LabVIEW calls the code associated
with the CIN, passing it the specified data.
After you have written your first CIN as described in this manual, writing
new CINs is relatively easy. The work involved in writing new CINs is
mostly in coding the algorithm, because the interface to LabVIEW remains
the same, no matter what the development system.
Note LabVIEW does not support code resources for external subroutines on the Power
Macintosh. If you are working with a Power Macintosh, you should use shared
libraries instead of external subroutines. For information on building shared
libraries, consult your development environment documentation.
Although LabVIEW for Solaris 2.x, HP-UX, and Concurrent PowerMAX support
external routines, it is recommended you use UNIX shared libraries instead,
because they are a more standard library format.
Supported Languages
The interface for CINs and external subroutines supports a variety of
compilers, although not all compilers can create code in the correct
executable format.
Macintosh
LabVIEW for the Macintosh uses external code as a customized code
resource (for 68K) or shared library (for Power Macintosh) that is prepared
for LabVIEW using the separate utilities lvsbutil.app for THINK C
and Metrowerks CodeWarrior, and lvsbutil.tool for the Macintosh
Programmer’s Workshop. These utilities are included with LabVIEW.
The LabVIEW utilities and object files are compatible with the three major
C development environments for the Power Macintosh:
• THINK C, version 7 for Macintosh and Symantec C++ version 8 for
Power Macintosh, from Symantec Corporation of Cupertino, CA
• Metrowerks CodeWarrior from Metrowerks Corporation of
Austin, Texas
• Macintosh Programmer’s Workshop (MPW) from Apple Computer,
Inc. of Cupertino, CA
CINs compiled for the 68K Macintosh will not be recognized by LabVIEW
for the Power Macintosh, and vice versa.
LabVIEW does not currently work with fat binaries (a format including
multiple executables in one file, in this case both 68K and Power
Macintosh executables).
Note Under Windows 95 and Windows NT, do not call CINs created using the
Watcom C compiler that call DLLs and system functions or that access hardware
directly. The technique Watcom uses to call such code under Windows 3.1 does
not work under Windows 95 or Windows NT.
Solaris
LabVIEW for Sun supports external code compiled in a.out format under
Solaris 1.x and a shared library format under Solaris 2.x. These formats are
prepared for LabVIEW using a LabVIEW utility.
The HP-UX C/ANSI C compiler and Concurrent C Compiler are the only
compilers tested thoroughly with LabVIEW.
If you execute the VI at this point, and the block diagram needs to execute
the CIN, LabVIEW calls the CIN object code and passes any data wired to
the CIN. If you save the VI after loading the code, LabVIEW saves the CIN
object code along with the VI so LabVIEW no longer needs the original
code to execute the CIN. You can update your CIN object code with new
versions at any time.
The examples directory contains a cins directory that includes all of the
examples given in this manual. The names of the directories in the cins
directory correspond to the CIN name given in the examples.
Input-Output Terminals
By default, a terminal pair is input-output; the left terminal is the input
terminal, and the right terminal is the output terminal. As an example,
consider a CIN that has a single terminal pair. Assume a 32-bit integer
control is wired to the input terminal, and a 32-bit integer indicator is
wired to the output terminal, as shown in the following illustration.
When the VI calls the CIN, the only argument LabVIEW passes to the CIN
object code is a pointer to the value of the 32-bit integer input. When the
CIN completes, LabVIEW then passes the value referenced by the pointer
to the 32-bit integer indicator. When you wire controls and indicators to the
input and the output terminals of a terminal pair, LabVIEW assumes the
CIN can modify the data passed. If another node on the block diagram
needs the input value, LabVIEW may have to copy the input data before
passing it to the CIN.
Now consider the same CIN, but with no indicator wired to the output
terminal, as shown in the following illustration.
not copy the data. The source code should not modify the value passed into
the input terminal of a terminal pair if you do not wire the output terminal.
If the CIN does modify the input value, nodes connected to the input
terminal wire may receive the modified data.
Output-Only Terminals
If you use a terminal pair only to return a value, make it an output-only
terminal pair by selecting Output Only from the terminal pair pop-up
menu. If a terminal pair is output-only, the input terminal is gray, as
shown in the following illustration.
Create .c File
If you select Create .c File... from the CIN pop-up menu, as shown in
the following illustration, LabVIEW creates a .c file in the style of the
C programming language. The .c file describes the routines you must
write and the data types for parameters that pass to the CIN.
For example, consider the following call to a CIN, which takes a 32-bit
integer as an input and returns a 32-bit integer as an output.
The following code excerpt is the initial .c file for this node. Eight routines
may be written for the CIN. The CINRun routine is required—the others are
optional. If an optional routine is not present, a default routine is supplied
when the CIN is built.
LabVIEW calls the CINRun routine when it is time for the node to
execute. CINRun receives the input and output values as parameters. The
other routines (CINLoad, CINSave, CINUnload, CINAbort, CINInit,
CINDispose, and CINProperties) are housekeeping routines, called at
specific times to give you the opportunity to take care of specialized tasks
with your CIN. For instance, CINLoad is called when a VI is first loaded.
If you need to accomplish some special task when your VI is first loaded,
put the code for that task in the CINLoad routine. To do this, write your
CINLoad routine as follows:
CIN MgErr CINLoad(RsrcFile reserved) {
Unused (reserved);
/* ENTER YOUR CODE HERE */
return noErr;
}
In general, you only need to write the CINRun routine. The other routines
are supplied for instances when you have special initialization needs, such
as when your CIN must maintain some information across calls, and you
want to preallocate or initialize global state information. The following
code shows how to fill out the CINRun routine from the previously shown
LabVIEW-generated .c file to multiply a number by two. This code is
included for illustrative purposes. Chapter 2, CIN Parameter Passing,
discusses how LabVIEW passes data to a CIN, with several examples.
CIN MgErr CINRun(int32 *num_in, int32 *num_out) {
*num_out = *num_in * 2;
return noErr;
}
You need not use these macros in any of the eight predefined entry points
(CINRun, CINLoad, CINUnload, CINSave, CINInit, CINDispose,
CINAbort, and CINProperties), because the CIN libraries already
establish and restore the global context before and after calling these
routines. Using them here would be harmless, but unnecessary.
However, if you create any other entry points to your CIN, you should
use these macros. You create another entry point to your CIN whenever
you pass the address of one of your functions to some other piece of code
that may call your function later. An example of this is the use of the
QSort routine in the LabVIEW support manager (described in the CIN
Function Overview section of the LabVIEW Online Reference). You must
pass a comparison routine to QSort. This routine gets called directly by
QSort, without going through the CIN library. Therefore it is your
responsibility to set up your global context with ENTERLVSB and
LEAVELVSB.
To use these macros properly, place the ENTERLVSB macro at the beginning
of your function between your local variables and the first statement of the
function. Place the LEAVELVSB macro at the end of your function just
before returning, as in the following example.
CStr gNameTable[kNNames];
int32 MyComparisonProc(int32 *pa, int32 * pb)
{
int32 comparisonResult;
ENTERLVSB
comparisonResult = StrCmp(gNameTable[*pa],
gNameTable[*pb]);
LEAVELVSB
return comparisonResult;
}
When you use these macros, be sure your function does not return
before calling the LEAVELVSB macro. One technique is to use a goto
endOfFunction statement (where endOfFunction is a label just before
the LEAVELVSB macro at the end of your function) in place of any return
statements you may place in your function.
Note Compiling the source code is different for each platform. Look under the heading
for your platform and compiler in the following sections to find the instructions
for your system.
Every source code file for a CIN should list #include "extcode.h" before any
other code. If your code needs to make system calls, you should also use #include
"hosttype.h" immediately after #include "extcode.h".
Macintosh
LabVIEW for the Macintosh uses external code as a customized code
resource (on a 68K Macintosh) or as a shared library (on a Power
Macintosh) prepared for LabVIEW using the separate utilities
lvsbutil.app for THINK and Metrowerks or lvsbutil.tool for
MPW. Both these utilities are included with LabVIEW.
You can create CINs on the Macintosh with compilers from any of the three
major C compiler vendors: Symantec’s THINK environment, Metrowerks’
CodeWarrior environment, and Apple’s Macintosh Programmer’s
Workshop (MPW) environment. Always use the latest Universal headers
containing definitions for both 68K and Power Macintosh compilers.
The LabVIEW utilities for building Power Macintosh CINs are the same
ones used for the 68K Macintosh and can be used to build both versions
of a CIN. If you want to place both versions in the same folder, however,
some development conflicts may arise. Because the naming conventions
for object files and.lsb files are the same, make sure one version does not
replace the other. These kinds of issues can be handled in different ways,
depending on your development environment.
Some CIN code that compiles and works on the 68K Macintosh and calls
Macintosh OS or Toolbox functions requires changes to the source code
before it will work on the Power Macintosh. Any code that passes a
function pointer to a Mac OS or Toolbox function must be modified to
pass a Routine Descriptor (see Apple’s Inside Macintosh chapter on the
Mixed Mode Manager, available in the Macintosh on RISC SDK from
APDA). Also, if you use any 68K assembly language in your CIN, it must
be ported to either C or Power Macintosh assembly language.
With THINK C 7, an easy way to set up your CIN project is to make use
of the project stationery in the cintools:Symantec-THINK Files:
Project Stationery folder. For THINK C 7 projects, the project
stationery is a folder called LabVIEW CIN TC7. It provides a template
for new CINs with most of the settings you need. See the Read Me file in
the Project Stationery folder for details.
When building a CIN using THINK C for 68K, many of the preferences
can be set to whatever you wish. Others, however, must be set to specific
values to correctly create a CIN. If for some reason you do not use the
CIN project stationery, you will need to ensure the following settings in
the THINK C Preferences dialog box are made:
• Pull down the THINK C Edit menu and pop up on the Options item;
select THINK Project Manager.... Under Preferences, check the
Generate link map box, and then click on the OK button. Now go
back to the Options item under the Edit menu and select THINK C....
• To complete the project set-up process, select the Require prototypes
button under Language Settings and then check the Check Pointer
Types box. Under Prefix, delete the line #include <MacHeaders>
if it is present. Finally, under Compiler Settings, check the Generate
68881 instructions box, the Native floating-point format box, and
the Generate 68020 instructions box. You can use the Copy button
at the top of the dialog box to make these settings the default settings
for new projects, which will make the set-up process for subsequent
CINs simpler.
• When you have finished selecting the options in the Edit menu, turn
to the THINK C Project menu; select Set Project Type.... First, set
the type to Code Resource. From the new options that appear, set the
File Type to .tmp, the Creator to LVsb, the Name to the name of the
CIN plus the extension .tmp, the Type to CUST, the ID to 128, and
check the Custom Header box. If you are creating a CIN called
test, you must name the resource test.tmp, as shown in the
following illustration.
After these parameters are set, add the libraries CINLib.TC7 and
LabVIEWLib.TC7, found in cintools:Symantic-THINK Files:
Think C 7 Libraries, to the project. You must also add the default
version of each standard CIN procedure not defined by your code.
Each default procedure is in its own correspondingly named library,
located in cintools:Symantic-THINK Files:THINK C 7
Libraries. These libraries are CINLoad.TC7, CINUnload.TC7,
CINInit.TC7, CINDispose.TC7, CINAbort.TC7, CINSave.TC7,
and CINProperties.TC7. Then add your .c files.
You are now ready to build the code resource. Go to the Project menu
and select Build Code Resource.... A dialog box will appear, allowing
you to save the code resource. The name of the code resource must be
the same as the name of the CIN plus the extension .tmp.
After you build a code resource and give it a .tmp extension, you must run
the application lvsbutil.app, also included with LabVIEW, to prepare
external code for use as a CIN or external subroutine. This utility prompts
you to select your .tmp file. The utility also uses the THINK C link map
file, which carries a .map extension and must be in the folder with your
.tmp file. The application lvsbutil.app uses the .tmp and the .map
files to produce a .lsb file that can be loaded into a VI.
If you are making a CIN, select the CIN option in the dialog box, as shown
in the above illustration. If you are making a CIN for the Power Macintosh,
also check the For Power PC box. If you are making an external
subroutine, select the Subroutine option.
Advanced programmers can check the Add separate resource file box to
add additional resources to their CINs or the Put directly into VI box to
put the .lsb code into a VI without opening it or launching LabVIEW.
Remember the VI designated to receive the .lsb code must already
contain .lsb code with the same name. Notice you cannot put the code
directly into a library.
If your .tmp code resource file does not show up in the dialog box, check
its file type. When building the .tmp file, specify the file type as .tmp,
which is under the Set Project Type... menu item of the Project menu in
THINK C. The .lsb file this application produces is what the LabVIEW
CIN node should load.
Note The THINK C compiler will only find extcode.h if the file extcode.h is located
on the THINK C search path. You can place the cintools folder in the same
folder as your THINK C application, or you can make sure the line #include
"extcode.h" is a full pathname to extcode.h under THINK C. For example:
#include "harddrive:cintools:extcode.h"
If you are using System 7.0 or later, you can extend the THINK C search path.
To do so, first create a new folder in the same folder as your THINK C project and
name it Aliases. Then make an alias for the cintools folder, and drag this alias
into your newly created Aliases folder. This technique enables the include line
to read #include "extcode.h"; therefore, it is not necessary to type the full
pathname.
You need the following files in your project to create a CIN for Power
Macintosh.
• ~CINLib.ppc. This file is shipped with LabVIEW and can be found
in the cintools:Symantic-THINK Files:Symantic C 8 folder.
• Your source files
You might also need the LabVIEW.xcoff file. This file is shipped with
LabVIEW and can be found in the cintools:PowerPC Libraries
folder. It is needed if you call any routines within LabVIEW, such as
DSSetHandleSize() or SetCINArraySize().
An easy way to set up your CIN project is to make use of the CIN
project stationery in the cintools:Symantec-THINK Files:Project
Stationery folder. For Symantec C version 8 projects the project
stationery is a folder called LabVIEW CIN SC8PPC. The folder provides
a template for new CINs containing almost all of the files and preference
settings you need. See the Read Me file in the Project Stationery
folder for details.
When building a CIN using Symantec C++ for PowerMac, you can set
many of the preferences to whatever you wish. Others, however, must be
set to specific values to correctly create a CIN. If you do not use the CIN
project stationery, you need to make the following settings in the Symantec
Project Manager Options dialog box (accessed from the Project menu):
• Project Type—Set the Project Type pop-up menu to Shared Library.
Set the File Type text field to .tmp. Set the Destination text field to
cinName.tmp, where cinName is the name of your CIN. Set the
Creator to LVsb.
• Linker—Set the Linker pop-up menu to PPCLink & MakePEF.
Set the PPCLink settings text field to -export
Build the CIN by selecting Build Library from the Build menu. Then
convert the .tmp file with lvsbutil.app (with For PowerPC checked).
Note All of your files must be in a single segment. LabVIEW does not support
multi-segment CINs.
An easy way to set up your CIN project is to use the CIN project stationery
in the cintools:Metrowerks Files:Project Stationery folder.
For CodeWarrior 68K projects the project stationery is a file called
LabVIEW CIN MW68K. The file provides a template for CINs containing
almost all of the settings you need. See the Read Me file in the Project
Stationery folder for details.
When building a CIN using CodeWarrior for 68K, you can set many of
the preferences to whatever you wish. Others, however, must be set to
specific values to correctly create a CIN. If you do not use the CIN project
stationery, you need to make the following settings in the CodeWarrior
Preferences dialog box:
• Language—Set the Source Model pop-up menu to Apple C.
Empty the Prefix File text field.
• Processor—Check the 68881 Codegen and MPW C Calling
Conventions checkboxes. Leave the 4-Byte Ints and 8-Byte Doubles
checkboxes unchecked.
• Linker—Check the Generate Link Map checkbox.
• Project—Set the Project Type pop-up menu to Code Resource.
Set the File Name text field to cinName.tmp, where cinName is the
name of your CIN. Set the Resource Name text field to the same text
as in the File Name text field. Set the Type text field to .tmp and the
ResType text field to CUST. Set the ResID text field to 128. Set the
Header Type pop-up menu to Custom. Set the Creator to LVsb.
• Access Paths—Add your cintools folder to the list of access paths.
Build the CIN by selecting Make from the CodeWarrior Project menu.
Caution This operation will destroy the contents of any other file named cinName.tmp
! in that folder. This could easily be the case if this is the same folder in which
you build a Power Macintosh version of your CIN. If you are building for both
platforms, you should keep separate directories for each. The convention used
by the MPW CIN tools is to have two subdirectories named PPCObj and M68Obj
where all platform-specific files reside.
Note If you have both a ThinkC68K and a MetrowerksC68K map file, lvbutil cannot
know in advance which compiler your .tmp file came from. It will first look for a
ThinkC .map file, then for a Metrowerks .map file. To avoid any conflict, remove
the unnecessary .map file before using lvsbutil.app.
When you have successfully built the cinName.tmp file, you must then
use the lvsbutil.app application to create the cinName.lsb file.
Caution This operation will destroy the contents of any previous file named cinName.lsb
! in that folder. This could easily be the case if this is the same folder in which you
build a 68K Macintosh version of your CIN.
You may also need the LabVIEW.xcoff file. This file is shipped with
LabVIEW and is found in the cintools:PowerPC Libraries folder.
It is needed if you call any routines within LabVIEW e.g.,
DSSetHandleSize(), or SetCINArraySize().
Finally, if you call any routines from a system shared library, you must add
the appropriate shared library interface file to your project's file list.
An easy way to set up your CIN project is to make use of the CIN
project stationery in the cintools:Metrowerks Files:Project
Stationery folder. For CodeWarrior PowerPC projects the project
stationery is a file called LabVIEW CIN MWPPC. This file provides a
template for CINs containing almost all of the settings you need. See
the Read Me file in the Project Stationery folder for details.
When building a CIN using CodeWarrior for PPC, you can set many of
the preferences to whatever you wish. Others, however, must be set to
specific values to correctly create a CIN. If you do not use the CIN project
stationery, you need to make the following settings in the CodeWarrior
Preferences dialog box:
• Language—Set the Source Model pop-up menu to Apple C. Empty
out the Prefix File text field (using MacHeaders will not work).
• Processor—Set the Struct Alignment pop-up menu to 68K.
• Linker—Empty all of the Entry Point fields.
• PEF—Set the Export Symbols pop-up menu to Use .exp file
and place a copy of the file projectName.exp (found in your
cintools:Metrowerks Files:PPC Libraries folder) in the
same folder as your CodeWarrior project. Rename this file to
projectName.exp, where projectName is the name of the project
file. CodeWarrior will look in this file to determine what symbols
your CIN exports. LabVIEW needs these to link to your CIN.
• Project—Set the Project Type pop-up menu to Shared Library.
Set the file name to be cinName.tmp, where cinName is the name of
your CIN. Set the Type field to .tmp. Set the Creator to LVsb.
• Access Paths—Add your cintools folder to the list of access paths.
Build the CIN by selecting Make from the CodeWarrior Project menu.
Caution This operation will destroy the contents of any other file named cinName.tmp in
! that folder. This could easily be the case if this is the same folder in which you
build a 68K Macintosh version of your CIN. If you are building for both platforms,
you should keep separate folders for each. The convention used by the MPW CIN
tools is to have two subdirectories named PPCObj and M68Obj where all
platform-specific files reside.
When you have successfully built the cinName.tmp file, you must then
use the lvsbutil.app application to create the cinName.lsb file.
Caution This operation will destroy the contents of any previous file named cinName.lsb
! in that folder. This could easily be the case if this is the same folder in which you
build a 68K Macintosh version of your CIN.
CINMake can be used for building both Power Macintosh and 68K
Macintosh versions of your CINs. By default, the CINMake script
builds 68K Macintosh CINs and puts the resulting cinName.lsb into
the M68Obj folder.
You must have one makefile for each CIN. Name the makefile by
appending .lvm to the CIN name. This indicates this is a LabVIEW
makefile. The makefile should resemble the following pseudocode.
Be sure each Dir command ends with the colon character (:).
cinToolsDir = cinToolsDir:
Complete pathname to the LabVIEW
cintools:MPW folder, which is located
in the LabVIEW folder.
otherM68ObjFiles = otherM68ObjFiles
(optional) For 68K Macintosh only,
list of additional object files (files with
a .o extension) your code needs to
compile. Separate the names of files
with spaces.
otherPPCObjFiles = otherPPCObjFiles
(optional) For Power Macintosh only,
list of additional object files (files with
a .o extension) your code needs to
compile. Separate the names of files
with spaces.
ShLibs = sharedLibraryNames
(optional) For Power Macintosh only,
a space-separated list of the link-time
copies of import libraries with which
the CIN must be linked. Each should be
a complete path to the file.
ShLibMaps = sharedLibMappings
(optional) For Power Macintosh only, the
command-line arguments to the MakePEF
tool that indicate the mapping between
the name of each link-time import library
and the run-time name of that import
library. These will usually look
something like the following:
-librename libA.xcoff=libA
-librename libB.xcoff=libB
You must adjust the —Dir names to reflect your own file system hierarchy.
If CINMake does not find a .lvm file in the current folder, it builds a
file named cinName.lvm, and prompts you for necessary information.
This file, cinName.lvm, is in a format compatible with building both
Power Macintosh and 68K Macintosh CINs in the same folder. If CINMake
finds a cinName.lvm but it does not have the line LVMVers = 2, saves the
.lvm file in cinName.lvm.old and update the cinName.lvm file to be
compatible with the new version of CINMake.
-Rshell
You can use LVMakeMake to build an MPW makefile you can then
customize for your own purposes. You should only have to run
LVMakeMake once for a given CIN. You can modify the resulting makefile
by adding the proper header file dependencies, or by adding other object
files to be linked into your CIN. The format of a LVMakeMake command
follows, with optional parameters listed in brackets.
LVMakeMake [-o makeFile] [-PPC] <name of your CIN>.make
You can then use the MPW make tool to build your CIN, as shown in the
following commands.
make -f myCIN.ppc.make> myCIN.makeout
## creates the build commands
myCIN.makeout
## executes the build commands
You should load the .lsb file this application produces into your
LabVIEW CIN node.
The only compiler that currently supports the correct format of executables
is Watcom C. The following section lists the steps for compiling a CIN with
the Watcom compiler.
Watcom C Compiler
With the Watcom C compiler, you create a specification that includes the
name of the file you want to create, relevant directories, and any external
subroutines or object files the CIN needs. (External subroutines are
described in Chapter 4, External Subroutines.) You then use the wmake
utility included with Watcom to compile the CIN.
In addition to compiling the CIN, the makefile directs wmake to put the CIN
in the appropriate form for LabVIEW.
The makefile should look like the following pseudocode. Append .lvm to
the makefile name to indicate this is a LabVIEW makefile.
cinToolsDir = cinToolsDir
Complete or partial pathname to the
LabVIEW cintools directory, which is
located in the LabVIEW directory. This
directory contains header files you can
use for creating CINs, and tools the
wmake utility uses to create the CIN.
Note The wmake utility sometimes erroneously stops a make with an incorrectly
reported error when it is run in the DOS shell within Windows. If this happens,
run it in normal DOS.
Note You cannot link most of the Watcom C libraries to your CIN because precompiled
libraries contain code that cannot be properly resolved by LabVIEW when it links
a VI to a CIN. If you try to call those functions, your CIN may crash.
Symantec C
The process for creating CINs using Symantec C is similar to the
process for Visual C++ Command Line. Use smake instead of nmake
on your .lvm file.
To create CINs using Watcom C for Windows 3.1, follow the Watcom C
instructions given in the Watcom C Compiler subsection of the Compile the
CIN Source Code section of this chapter. You must compile the source code
for the CINs under Windows 3.1. Use the LabVIEW for Windows 3.1
CIN libraries to compile the CINs.
Solaris 1.x
LabVIEW for Sun can use external code compiled in a.out format
and prepared for LabVIEW using a LabVIEW utility. The unbundled
Sun C compiler is the only compiler tested thoroughly with LabVIEW.
Other compilers that can generate code in a.out format might also work
with LabVIEW, but this has not been verified. The C compiler that comes
with the operating system does not use extended-precision floating-point
numbers; code using this numeric type will not compile. However, the
unbundled C compiler does use them.
Solaris 2.x
The preceding information for Solaris 1.x is true for Solaris 2.x, with one
exception—LabVIEW 3.1 and higher for Solaris 2.x uses code compiled in
a shared library format, rather than the a.out format previously specified.
Note LabVIEW 3.0 for Solaris 2.x supported external code compiled in ELF format.
Existing Solaris 1.x and Solaris 2.x (for LabVIEW 3.0) CINs will not
operate correctly if they reference functions not in the System V Interface
Definition (SVID) for libc, libsys, and libnsl. Recompiling your
existing CINs using the shared library format should ensure your CINs
function as expected.
The format for the lvmkmf command follows, with optional parameters
listed in brackets.
lvmkmf [-o Makefile] [-t CIN] [-ext Gluefile] LVSBName
LVSBName, the name of the CIN or external subroutine you want to build,
is required. If LVSBName is foo, the compiler assumes the source is foo.c,
and the compiler names the output file foo.lsb.
-o is optional and supplies the name of the makefile lvmkmf creates. If you
do not use this option, the makefile name defaults to Makefile.
-t is optional and indicates the type of external code you want to create.
For CINs, you should use CIN, which is the default.
If you specify the -ext argument to the lvmkmf script, the makefile creates
temporary files. For example, if the gluefile name is bar, the makefile
creates files bar.s and bar.o. Neither the CIN nor the makefile needs
these files after the CIN has been created.
This command loads your object code into memory and links the code
to the current front panel/block diagram. After you save the VI, the file
containing the object code does not need to be resident on the computer
running LabVIEW for the VI to execute.
If you make modifications to the source code, you can load the new
version of the object code using the Load Code Resource option. The file
containing the object code for the CIN must have an extension of .lsb.
For general information about the memory manager, the file manager, and
the support manager, see Chapter 5, Manager Overview.
Online Reference
For descriptions of functions or file manager data structures, refer to the
CIN Function Overview section of the LabVIEW Online Reference,
available by selecting Help»Online Reference.
Pointers as Parameters
Some manager functions have a parameter that is a pointer.
These parameter type descriptions are identified by a trailing asterisk
(such as the hp parameter of the AZHandToHand memory manager
function documented in the CIN Function Overview section of the
LabVIEW Online Reference) or are type defined as such (such as
the name parameter of the FNamePtr function documented in the
CIN Function Overview section of the LabVIEW Online Reference).
In most cases, this means the manager function will write a value to
pre-allocated memory. In some cases, such as FStrFitsPath or
GetALong, the function reads a value from the memory location,
so you don’t have to pre-allocate memory for a return value.
Table 1-1 lists the functions with parameters that return a value for which
you must pre-allocate memory.
FGetEOF
Correct example:
foo(Path path) {
Str255 buf; /* allocated buffer of 256 chars */
File fd;
MgErr err;
err = FNamePtr(path, buf);
err = FMOpen(&fd, path, openReadOnly,
denyWriteOnly);
}
Incorrect example:
foo(Path path) {
PStr p; /* an uninitialized pointer */
File *fd; /* an uninitialized pointer */
MgErr err;
err = FNamePtr(path, p);
err = FMOpen(fd, path, openReadOnly
denyWriteOnly);
}
In the correct example, buf contains space for the maximum-sized Pascal
string (whose address is passed to FNamePtr), and fd is a local variable
(allocated space) for a file descriptor.
Use the DbgPrintf function to create this debugging window. The format
for DbgPrintf is similar to the format of the SPrintf function, which is
described in the CIN Function Overview section of the LabVIEW Online
Reference. DbgPrintf takes a variable number of arguments, where the
first argument is a C format string.
DbgPrintf
syntax int32 DbgPrintf(CStr cfmt, ..);
The first time you call DbgPrintf, LabVIEW opens a window to display
the text you pass to the function. Subsequent calls to DbgPrintf append
new data as new lines in the window (you do not need to pass in the new
line character to the function). If you call DbgPrintf with NULL instead of
a format string, LabVIEW closes the debugging window. You cannot
position or change the size of the window.
3. Run LabVIEW.
If you built your CIN from the command line, start LabVIEW
normally. When the debugger trap is run, a dialog box appears:
A Breakpoint has been reached. Click OK to terminate
application. Click CANCEL to debug the application.
Click CANCEL. This launches the debugger, which attaches to
LabVIEW, searches for the DLLs, then asks for the source file of
your CIN. Point it to your source file, and the debugger loads the
CIN source code. You can then debug your code.
If you built your CIN using the IDE, open your CIN project and
click the GO button. LabVIEW will be launched by Visual C.
See the xdb manual for more information. Once the CIN is loaded, break
into the debugger and set your breakpoints. You may need to qualify
function names with the name of the shared library. Qualified names are
in the form function_name@library_name. The name of the shared
library will not be what it was when compiled. Instead, it will be a unique
name generated by the C library function tmpnam. The name will always
begin with the string LV. Use the debugger command mm to display the
memory map of all currently loaded shared libraries. CIN shared libraries
are ordered by load time on the name space, so CINs loaded later appear
in the memory map before CINs loaded earlier. As an example, to break
at CINRun for the library /usr/tmp/LVAAAa17732, set the breakpoint
as follows:
>b CINRun@LVAAAa17732
If you reload a CIN that is already loaded, the debugger will not function
properly. If you change a CIN, you must quit and restart the debugger to
enable it to work as desired.
Introduction
LabVIEW passes parameters to the CINRun routine. These parameters
correspond to each of the wires connected to the CIN. You can pass any
data type to a CIN you can construct in LabVIEW; there is no limit to the
number of parameters you can pass to and from the CIN.
CIN .c File
When you select the Create .c File... option, LabVIEW creates a .c file in
which you can enter your CIN code. The CINRun function and its prototype
are given, and its parameters are typed to correspond to the data types being
passed to the CIN in the block diagram. If you want to refer to any of the
other CIN routines (CINInit, CINLoad, and so on), see their descriptions
in Chapter 1, CIN Overview.
The .c file created is a standard C file, except LabVIEW gives the data
types unambiguous names. C does not define the size of low-level data
types—the int data type might correspond to a 16-bit integer for one
compiler and a 32-bit integer for another compiler. The .c file uses names
explicit about data type size, such as int16, int32, float32, and so on.
LabVIEW comes with a header file, extcode.h, that contains typedefs
associating these LabVIEW data types with the corresponding data type
for the supported compilers of each platform.
Note You should always use #include "extcode.h" at the beginning of your source
code. If your code needs to include system header files, you should include
"extcode.h", "hosttype.h", and then any system header files, in that order.
If you write a CIN that accepts a single 32-bit signed integer, the .c file
indicates the CINRun routine is passed an int32 by reference. extcode.h
typedefs an int32 to the appropriate data type for the compiler you use
(if it is a supported compiler); therefore, you can use the int32 data type
in external code you write.
Scalar Numerics
LabVIEW passes numeric data types to CINs by passing a pointer to the
data as an argument. In C, this means LabVIEW passes a pointer to the
numeric data as an argument to the CIN. Arrays of numerics are described
in the subsequent Arrays and Strings section of this chapter.
Scalar Booleans
LabVIEW stores Booleans in memory as 8-bit integers. If any bit of the
integer is 1, the Boolean is TRUE; otherwise the Boolean is FALSE.
LabVIEW passes Booleans to CINs with the same conventions as for
numerics.
Note In LabVIEW 4.x and earlier, Booleans were stored as 16-bit integers. If the
high bit of the integer was 1, the Boolean was TRUE; otherwise the Boolean
was FALSE.
Refnums
LabVIEW treats a refnum the same way as it treats a scalar number and
passes refnums with the same conventions it uses for numbers.
Clusters of Scalars
For a cluster, LabVIEW passes a pointer to a structure containing the
elements of the cluster. LabVIEW stores fixed-size values directly as
components inside of the structure. If a component is another cluster,
LabVIEW stores this cluster value as a component of the main cluster.
The LabVIEW header file extcode.h, defines the word CIN to be either
Pascal or nothing, depending on the platform. Prefacing a function with the
word Pascal causes some C compilers to use Pascal calling conventions
instead of C calling conventions to generate the code for the routine.
LabVIEW uses Pascal calling conventions on the Macintosh when calling
CIN routines, so the header file declares the word CIN to be equivalent to
Pascal on the Macintosh. On the PC and Unix, however, LabVIEW uses
standard C calling conventions, so the header file declares the word CIN
to be equivalent to nothing.
This .c file contains a prototype and a template for the CIN’s CINRun
routine. LabVIEW calls the CINRun routine when the CIN executes.
In this example, LabVIEW passes CINRun the addresses of the three
32-bit floating-point numbers. The parameters are listed left to right in
the same order as you wired them (top to bottom) to the CIN. Thus, A,
B, and A_B are pointers to A, B, and A*B, respectively.
As described in the CIN .c File section of this chapter, the float32
data type is not a standard C data type. When LabVIEW creates a .c
file, it gives unambiguous names for data types. For most C compilers,
the float32 data type corresponds to the float data type. However,
this may not be true in all cases, because the C standard does not define
the sizes for the various data types. You can use these LabVIEW data
types in your code because extcode.h associates these data types
with the corresponding C data type for the compiler you are using. In
addition to defining LabVIEW data types, extcode.h also prototypes
LabVIEW routines you can access. These data types and routines are
described in Chapter 5, Manager Overview, of this manual and in the
CIN Function Overview section of the LabVIEW Online Reference.
Note The line #include "extcode.h" must be a full pathname to extcode.h under
THINK C. For example: #include "harddrive:cintools:extcode.h"
Optionally, System 7.x users can use the Aliases folder technique described in
the THINK C for 68K (Version 7) subsection of Chapter 1, CIN Overview, to enable
the include line to read #include "extcode.h".
For this multiplication example, fill in the code for the CINRun routine.
You do not have to use the variable names LabVIEW gives you in
CINRun; you can change them to increase the readability of the code.
CIN MgErr CINRun (float32 *A, float32 *B,
float32 *A_B);
{
*A_B = *A * *B;
return noErr;
}
CINRun multiplies the values to which A and B refer and stores the
results in the location to which A_B refers. It is important CIN routines
return an error code, so LabVIEW knows if the CIN encountered any
fatal problems and handles the error correctly.
If you return a value other than noErr, LabVIEW stops the execution
of the VI.
5. After creating the source code, you need to compile it and convert it
into a form LabVIEW can use. The following sections summarize the
steps for each of the supported compilers.
Note Step 5 is different for each platform. Look under the heading for your platform
and compiler in the following sections to find the instructions for your system.
For details, refer to the relevant subsection within the Compile the CIN Source
Code section in Chapter 1, CIN Overview.
(THINK C for 68K and Symantec C++) Create a new project and place
mult.c in it. Build mult.lsb according to the instructions in the
THINK C for 68K (Version 7) or the Symantec C++ 8.0 for Power
Macintosh of the Compile the CIN Source Code section of Chapter 1.
(Macintosh Programmer’s Workshop for 68K and Power Macintosh) Create
a file named mult.lvm. Make sure the name variable is set to mult.
Build mult.lvm according to the instructions in the Macintosh
Programmer’s Workshop for 68K and Power Macintosh subsection
of the Compile the CIN Source Code section of Chapter 1.
(Metrowerks CodeWarrior for Power Macintosh and 68K) Create a new
project and place mult.c in it. Build mult.lsb according to the
instructions in the Metrowerks CodeWarrior for 68K subsection of
the Compile the CIN Source Code section of Chapter 1.
(Watcom C Compiler for Window 3.x) Create a file named mult.lvm.
Make sure the name variable is set to mult. Build mult.lvm
according to the instructions in the Watcom C Compiler subsection
of the Compile the CIN Source Code section of Chapter 1.
(Microsoft Visual C++ Compiler Command Line and Symantec C for
Windows 95 and Windows NT) Create a file named mult.lvm. Make
sure the name variable is set to mult. Build mult.lvm according to
the instructions in the Visual C++ IDE subsection of the Compile the
CIN Source Code section of Chapter 1.
(Microsoft Visual C++ Compiler IDE for Windows 95 and Windows NT) Create
a project according to the instructions in the Visual C++ IDE
subsection of the Compile the CIN Source Code section of Chapter 1.
(All Unix Compilers) As described in the Steps for Creating a CIN
section of Chapter 1, CIN Overview, you can create a makefile using
the shell script lvmkmf. For this example, you should first enter the
following command.
lvmkmf mult
If you followed the preceding steps correctly, you should be able to run
the VI at this point. If you save the VI, the CIN object code is saved along
with the VI.
The diagram for this CIN is shown in the following illustration. Save the VI
as aequalb.vi.
Create a .c file for the CIN, and name it aequalb.c. The .c file
LabVIEW creates is as follows.
/*
* CIN source file
*/
#include "extcode.h"
CIN MgErr CINRun(float32 *ap, float32 *bp,
LVBoolean *aequalbp);
CIN MgErr CINRun(float32 *ap, float32 *bp,
LVBoolean *aequalbp) {
if (*ap == *bp)
*aequalbp= LVTRUE;
else
*aequalbp= LVFALSE;
return noErr;
}
Alignment Considerations
When a CIN returns variably sized data, you need to adjust the size of
the handle that references the array. One method of adjusting the handle
size is to use the memory manager routine DSSetHandleSize or, if the
data is stored in the application zone, the AZSetHandleSize routine, to
adjust the size of the return data handle. Both techniques work, but they
are trouble-prone because you have to calculate the size of the new
handle correctly. It is difficult to calculate the size correctly in a
platform-independent manner, however, because some platforms
have special requirements about how you align and pad memory.
Note LabVIEW 4.x stored Boolean arrays in memory as a series of bits packed to
the nearest 16-bit word. LabVIEW 4.x ignored unused bits in the last word.
LabVIEW 4.x ordered the bits from left to right; that is, the most significant
bit (MSB) is index 0. As with other arrays, a 4-byte dimension size preceded
Boolean arrays. The dimension size for LabVIEW 4.x Boolean arrays
indicates the number of valid bits contained in the array.
Paths (Path)
The exact structure for Path data types is subject to change in future
versions of LabVIEW. A Path is a dynamic data structure LabVIEW
passes the same way it passes arrays. LabVIEW stores the data for Paths
in an application zone handle. For more information about the functions
that manipulate Paths, refer to the CIN Function Overview section of the
LabVIEW Online Reference.
SetCINArraySize
syntax MgErr SetCINArraySize (UHandle dataH, int32
paramNum, int32 newNumElmts);
SetCINArraySize resizes a data handle based on the data structure of an argument you pass
to the CIN. It does not set the array dimension field.
returns MgErr, which can contain the errors in the following list. MgErrs are
discussed in Chapter 5, Manager Overview.
Error Description
noErr No error.
mFullErr Not enough memory to perform operation
mZoneErr Handle is not in specified zone.
NumericArrayResize
syntax MgErr NumericArrayResize(int32 typeCode, int32
numDims, UHandle *dataHP, int32
totalNewSize);
NumericArrayResize resizes a data handle referring to a numeric array. This routine also
accounts for alignment issues. It does not set the array dimension field. If *dataHP is NULL,
LabVIEW allocates a new array handle in *dataHP.
returns MgErr, which can contain the errors in the following list.
Error Description
noErr No error.
mFullErr Not enough memory to perform operation.
mZoneErr Handle is not in specified zone.
This example gives only the diagram and the code. Follow the instructions
in Chapter 1, CIN Overview, to create this CIN.
The diagram for this CIN is shown in the following illustration. Save the VI
as lstrcat.vi.
Create a .c file for the CIN, and name it lstrcat.c. The .c file
LabVIEW creates is as follows.
/*
* 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;
}
After resizing the string handle, this example copies the second string to the
end of the first string using MoveBlock. 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.
This example shows only the front panel, block diagram, and source code.
Follow the instructions in the Steps for Creating a CIN section of
Chapter 1, CIN Overview, to create the CIN.
The front panel for this VI is shown in the following illustration. Save the
VI as cross.vi.
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"
#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 ah, TD1Hdl bh, TD1Hdl
resulth, LVBoolean *errorp);
CIN MgErr CINRun(TD1Hdl ah, TD1Hdl bh, TD1Hdl
resulth, LVBoolean *errorp) {
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]) {
*errorp = LVTRUE;
goto out;
}
*errorp = 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)resulth,
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 an array with r rows and c columns, you can access the element at
row i and column j as shown in the following code fragment.
value = (*arrayh)–>arg1[i*c + j];
This example shows only the front panel, block diagram, and source code.
Follow the instructions in the Steps for Creating a CIN section of
Chapter 1, CIN Overview, to create the CIN.
The front panel for this VI is shown in the following illustration. Save the
VI as tblsrch.vi.
Save the .c file for the CIN as tblsrch.c. Following is the source code
for tblsrch.c with the CINRun routine added:
/*
* CIN source file
*/
#include "extcode.h"
#define ParamNumber 0
/* The array parameter is parameter 0 */
/*
* typedefs
*/
typedef struct {
int16 number;
LStrHandle string;
} TD2;
typedef struct {
int32 dimSize;
TD2 arg1[1];
} TD1;
typedef TD1 **TD1Hdl;
CIN MgErr CINRun(
TD1Hdl clusterTableh,
TD2 *elementp,
LVBoolean *presentp,
int32 *positionp);
CIN MgErr CINRun(
TD1Hdl clusterTableh,
TD2 *elementp,
LVBoolean *presentp,
int32 *positionp) {
int32 size,i;
MgErr err=noErr;
TD2 *tmpp;
LStrHandle newStringh;
TD2 *newElementp;
int32 newNumElements;
size = (*clusterTableh)–>dimSize;
tmpp = (*clusterTableh)–>arg1;
*positionp = –1;
*presentp = LVFALSE;
If the routine does not find the element, you have to add a new element
to the array. Use the memory manager routine DSHandToHand to create
a new handle containing the same string as the one in the cluster element
you passed to the CIN. CINRun then increases the size of the array using
SetCINArraySize and fills the last position with a copy of the element
you passed to the CIN.
If the SetCINArraySize call fails, the CIN returns the error code returned
by the manager. If the CIN is unable to resize the array, LabVIEW disposes
of the duplicate string handle.
CIN Routines
A CIN consists of several routines, as described by the .c file LabVIEW
creates when you select Create .c File... from the CIN pop-up menu.
The previous chapters have discussed only the CINRun routine. The
other routines are CINLoad, CINInit, CINAbort, CINSave,
CINDispose, CINUnload, and CINProperties.
It is important to understand that for most CINs, you need to write only
the CINRun routine. The other routines are supplied mainly for the cases
in which you have special initialization needs, such as when your CIN
is going to maintain some information across calls, and you want to
preallocate or initialize global state information.
Within your CIN code resource, you may have declared global data.
Global data includes variables declared outside of the scope of all
routines, and, for the purposes of this discussion, variables declared as
static variables within routines. LabVIEW allocates space for this global
data. As with the code itself, there is always only one instance of these
globals in memory. Regardless of how many nodes reference the code
resource and regardless of whether the surrounding VI is reentrant, there is
only one copy of these globals in memory, and their values are consistent.
When you create a CIN node, LabVIEW allocates a CIN data space,
a 4-byte storage location in the VI data space(s), strictly for the use of
the CIN node. Each CIN may have one or more CIN data spaces reserved
for the node, depending on how many times the node appears in a VI or
collection of VIs. You can use this CIN data space to store global data on
a per data space basis, as described in the Code Globals and CIN Data
Space Globals section later in this chapter.
VI
global storage
Figure 3-1. Data Storage Spaces for One CIN, Simple Case
A CIN node references the code resource by name, using the name
you specified when you created the code resource. When you load a VI
containing a CIN, LabVIEW looks in memory to see if a code resource
with the desired name is already loaded. If so, LabVIEW links the CIN
to the code resource for execution purposes.
This linking behaves the same way as links between VIs and subVIs. When
you try to reference a subVI and another VI with the same name already
exists in memory, LabVIEW references the one already in memory instead
of the one you selected. In the same way, if you try to load references to two
different code resources having the same name, only one code resource is
actually loaded into memory, and both references point to the same code.
The difference is that LabVIEW can verify a subVI call matches the subVI
connector pane terminal, but LabVIEW cannot verify your source code
matches the CIN call.
Loading a VI
When you first load a VI, LabVIEW calls the CINLoad routines for any
CINs contained in that VI. This gives you a chance to load any file-based
resources at load time, because LabVIEW calls this routine only when the
VI is first loaded (see the Loading a New Resource into the CIN section that
follows for an exception to this rule). After LabVIEW calls the CINLoad
routine, it calls CINInit. Together, these two routines perform any
initialization you need before the VI runs.
LabVIEW calls CINLoad once for a given code resource, regardless of the
number of data spaces and the number of references to that code resource.
This is why you should initialize code globals in CINLoad.
LabVIEW calls CINInit for a given code resource a total of one time
for each CIN data space multiplied by the number of references to the
code resource in the VI corresponding to that data space. If you want
to use CIN data space globals, you should initialize them in CINInit.
See the Code Globals and CIN Data Space Globals, the Loading a New
Resource into the CIN, and the Compiling a VI sections of this chapter
for related information.
Unloading a VI
When you close a VI front panel, LabVIEW checks to see if there are any
references to that VI in memory. If so, then the VI code and data space
remain in memory. When all references to a VI are removed from memory,
and its front panel is not open, that VI is unloaded from memory.
Compiling a VI
When you compile a VI, LabVIEW recreates the VI data space, resetting
all uninitialized shift registers, for instance, to their default values. In the
same way, your CIN is given a chance to dispose or initialize any storage
it manages. Before disposing of the current data space, LabVIEW calls the
CINDispose routine for each reference to the code resource within the
VI(s) being compiled to give the code resource a chance to dispose of any
old results it is managing. LabVIEW then compiles the VI and creates a
new data space for the VI(s) being compiled (multiple data spaces for any
reentrant VI). The CINInit routine is then called for each reference to the
code resource within the compiled VI(s) to give the code resource a chance
to create or initialize any data it wants to manage.
Running a VI
When you press the Run button of a VI, the VI begins to execute.
When LabVIEW encounters a code interface node, it calls the CINRun
routine for that node.
Saving a VI
When you save a VI, LabVIEW calls the CINSave routine for that VI,
giving you the chance to save any resources (for example, something you
loaded in CINLoad). Notice when you save a VI, LabVIEW creates a new
version of the file, even if you are saving the VI with the same name. If the
save is successful, LabVIEW deletes the old file and renames the new file
with the original name. Therefore, anything you expect to be able to load
in CINLoad needs to be saved in CINSave.
Aborting a VI
When you abort a VI, LabVIEW calls the CINAbort routine for every
reference to a code resource contained in the VI being aborted. The
CINAbort routine of all actively running subVIs is also called. If a CIN is
in a reentrant VI, it is called for each CIN data space as well. CINs in VIs
not currently executing are not notified by LabVIEW of the abort event.
After LabVIEW calls CINLoad, it calls CINInit once for each reference
to the CIN, because its CIN data space may need initialization. Thus, if you
have two nodes in the same VI, where both reference the same code, the
LabVIEW calls the CINLoad routine once, and the CINInit twice. If you
later load another VI referencing the same code resource, then LabVIEW
calls CINInit again for the new version. LabVIEW has already called
CINLoad once, and does not call it again for this new reference.
VI
global storage
(code globals)
VI data space code resource
4-byte CIN
data space
4-byte CIN
data space
4-byte CIN
data space
LabVIEW calls CINDispose and CINAbort for each individual CIN data
space. LabVIEW calls CINSave only once, regardless of the number of
references to a given code resource within the VI you are saving.
As with multiple instances of the same node, LabVIEW calls the CINInit,
CINDispose, and CINAbort routines for each individual CIN data space.
My VI My VI My VI
data space 1 data space 3
My VI
data space 2 code resource global storage
4-byte CIN
data space
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 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 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
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. 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 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 calling the same code resource
and each VI can have its own set of globals, if the VI is reentrant. 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
containing that CIN is not reentrant, it does not matter which method
you choose.
When you want to access that data, use GetDSStorage to retrieve the
handle and then dereference the appropriate fields (see the code for
CINRun in the following example). Finally, in your CINDispose routine
you need to dispose of the handle.
/*
* CIN source file
*/
#include "extcode.h"
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()
{
dsGlobalStruct **dsGlobals;
dsGlobals=(dsGlobalStruct **) GetDSStorage();
if (dsGlobals)
DSDisposeHandle(dsGlobals);
return noErr;
}
CIN MgErr CINRun(float64 *new_num, float64 *avg);
CIN MgErr CINRun(float64 *new_num, float64 *avg)
{
dsGlobalStruct **dsGlobals;
dsGlobals=(dsGlobalStruct **) GetDSStorage();
if (dsGlobals) {
(*dsGlobals)–>total += *new_num;
(*dsGlobals)–>numElements++;
*avg = (*dsGlobals)–>total /
(*dsGlobals)–>numElements;
}
return noErr;
}
Calling a Windows 95 or
Windows NT Dynamic Link Library
No special techniques are necessary to call a Windows 95 or Windows NT
DLL. Call DLLs the way you ordinarily would in a Windows 95 or
Windows NT program.
Before you attempt to link a dynamic link library with a CIN, first write a
C program calling it. Do this to ensure you are calling the DLL properly,
and the DLL behaves as expected. You can test the C program using the
debugging tools supplied by your compiler.
After you are sure the DLL works and you are calling it correctly, write
the 32-bit CIN that LabVIEW can call. The main purpose of this CIN is
to act as a go-between, translating LabVIEW 32-bit data to 16-bit data.
This CIN will take 32-bit pointers from LabVIEW and then call the DLL
with the appropriate arguments.
Note If you do not specify a full path, Windows searches the Windows directory,
the Windows system directory, the LabVIEW directory, and the directories listed
in the Path variable.
proc is the address of the function returned in step 3. Following that are the
parameters you want to pass to the DLL.
The DLL
Most Windows compilers can create a DLL. Regardless of the compiler
you use to create a DLL, the way you call it from a CIN will be roughly the
same. Because you must have Watcom C/386 to write a Windows CIN, the
following example is for a Watcom DLL. The process for creating a DLL
using the Watcom compiler is described in Chapter 38, Windows 32-Bit
Dynamic Link Libraries, of the Watcom C/386 User's Guide.
The following code is for a Watcom C/386 32-bit DLL that calls the
MessageBox function. The _16MessageBox function calls the Windows
MessageBox function; the only difference between these functions is the
former takes far 16-bit pointers, which are pointers passed to the DLL.
In this 32-bit environment, MessageBox expects near 32-bit pointers.
The DLL function will accept two parameters. The first is the message to
display in the window. The second is the title to display in the window.
Both parameters are C strings, meaning they are pointers to the characters
of the string, followed by a terminating null character. Save the code in a
file called MSGBXDLL.C.
/*
* MSGBXDLL.C
*/
#include <windows.h>
#include <dos.h>
void FAR PASCAL Lib1( LPSTR message,
LPSTR winTitle)
{
_16MessageBox( NULL,
message,
winTitle,
MB_OK | MB_TASKMODAL );
}
int PASCAL WinMain( HANDLE hInstance,
HANDLE x1,
LPSTR lpCmdLine,
int x2 )
{
DefineDLLEntry( 1,
(void *) Lib1,
DLL_PTR,
DLL_PTR,
DLL_ENDLIST );
return( 1 );
}
Enter the following commands at the DOS prompt to create the DLL.
C>wcc386 msgbxdll /zw
C>wlink @msgbxdll
C>wbind msgbxdll –d –n
Following is the LabVIEW block diagram for a VI calling a CIN that calls
the previously described DLL. It passes two LabVIEW strings to the CIN,
and the CIN returns an error code.
This example does not pass a full path to LoadLibrary. You should move
the DLL to the top level of your LabVIEW directory so it will be found.
See the note in the section 1. Load the DLL, earlier in this chapter for
more information.
/*
* CIN source file
*/
#include "extcode.h"
#include "hosttype.h"
#include <windows.h>
CIN MgErr CINRun(LStrHandle message,
LStrHandle winTitle,
int32 *err)
{
HANDLE hDLL = NULL;
FARPROC addr = NULL;
HINDIR hMessageBox;
int cb;
char *messageCStr = NULL,
*winTitleCStr = NULL;
MgErr cinErr = noErr;
*err=0;
hDLL = LoadLibrary("msgbxdll.dll");
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,
INDIR_WORD,
INDIR_ENDLIST );
if (!hMessageBox) {
*err = 3; /* GetIndirectFunctionHandle
failed */
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);
if (hDLL)
FreeLibrary(hDLL);
return cinErr;
}
The CIN first loads the library, and then gets the address of the DLL entry
point. As described in the Watcom C/386 User’s Guide, a Watcom DLL has
only one entry point, Win386LibEntry. Calling GetProcAddress for a
Watcom DLL requests the address of this entry point. For a DLL created
using a compiler other than the Watcom C compiler, request the address
of the function you want to call.
To prepare for the DLL call after getting the address, the example calls
GetIndirectFunctionHandle. Use this function to specify the data
types for the parameters you want to pass. The list is terminated with the
INDIR_ENDLIST value. Because there is only one entry point with a
Watcom DLL, pass an additional parameter (the INDIR_WORD parameter)
that is the number of the routine you want to call in the DLL. With a DLL
created using another compiler, you do not need to pass a function number,
because GetProcAddress returns the address of the desired function.
Notice at each stage of calling the DLL, the code checks for errors and
returns an error code if it fails.
Notice also 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 indicating 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.
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)
{
cb = (WORD)InvokeIndirectFunction(
hMessageBox,
messageCStr,
winTitleCStr,
0x1 );
out:
if (messageCStr)
DSDisposePtr(messageCStr);
if (winTitleCStr)
DSDisposePtr(winTitleCStr);
return cinErr;
}
CIN MgErr CINUnload(void)
{
if (hDLL)
FreeLibrary(hDLL);
return noErr;
}
Introduction
An external subroutine (or shared external subroutine) is a function you
can call from multiple external code modules. By placing common code in
an external subroutine, you can avoid duplicating the code in each external
code module. You can also use external subroutines to store information
that must be accessible to multiple external code modules.
You store external subroutines as files, so you have to give each one a
unique name. When LabVIEW searches for a subroutine file, it loads the
first file it finds with the correct name.
Note External subroutines are not supported on the Power Macintosh. The
Macintosh OS on the Power Macintosh uses shared libraries, which provide
a much cleaner mechanism for sharing code. If you need to share code among
multiple CINs on the Power Macintosh, consult your development environment
documentation to learn how to build a shared library.
You need to compile the calling code, even though its subroutines are not
all present. LabVIEW must be able to determine that your code calls an
external subroutine, find the subroutine, and load it into memory. When the
subroutine is loaded, LabVIEW must be able to modify the memory image
of the calling code so it correctly references the memory location of the
external code. Finally, LabVIEW may need to create and initialize memory
space the external subroutine uses for global data. The following sections
describe how to make this work.
External Subroutines
LabVIEW calls CINs, but only your code calls external subroutines.
Instead of creating seven routines ( CINRun, CINSave, and so on), you
create only one entry point (LVSBMain) for an external subroutine. When
another external code module calls this external subroutine, the LVSBMain
subroutine executes.
You compile an external subroutine almost the same way you compile a
CIN. Because multiple external code modules can call the same external
subroutine, LabVIEW does not load the code into a specific VI. Instead,
LabVIEW loads the code from the file created by the makefile when the
code is needed.
Macintosh
(THINK C Compiler and CodeWarrior 68K Compiler) To make a subroutine
using the THINK or CodeWarrior 68K C Compiler, build the code
resource (the .tmp file) as discussed in the Steps for Creating a CIN
section of Chapter 1, CIN Overview, but replace the CINLib library with
the appropriate LVSBLib library and select the subroutine option when
running lvsbutil.app.
Calling Code
You call external subroutines the same way you call standard
C subroutines. LabVIEW modifies the code at load time to ensure
the calling code passes control to the subroutine correctly.
When you call the external subroutine, do not use the function name
LVSBMain to call the function. Instead, use the name you gave the external
subroutine. If you created an external subroutine called fact.lsb, which
in turn contained an LVSBMain() subroutine, for example, you should call
the function as though it were named fact(). The argument list and return
type should be the same as the argument and return type for the
LVSBMain() subroutine.
You should also create a prototype for the function. This prototype should
have the keyword extern so the compiler will compile the CIN, even
though the subroutine is not present.
When you create the makefile for the CIN, you identify the names of
the external subroutines the CIN calls. The LabVIEW makefile embeds
information in your code LabVIEW uses to determine your code calls
external subroutines. When you load external code referencing external
subroutines into a VI, LabVIEW searches for the subroutine files. If it finds
the subroutines, LabVIEW performs the appropriate linking. If a file is not
found, LabVIEW displays a dialog box prompting you to find it. If you
dismiss the dialog box without selecting the file, the VI loads into memory
with a broken run arrow, indicating the VI is not executable.
Macintosh
(THINK C Compiler) The THINK C project must have an extra file named
glue.c specifying each external subroutine. Each reference to the external
subroutine should have an entry as follows in the glue.c file:
long gLVSB<external subroutine name> = 'LVSB';
void <external subroutine name>(void);
void <external subroutine name>(void) {
asm {
move.l gLVSB<external subroutine name>, a0
jmp (a0)
}
}
(CodeWarrior 68K Compiler) The CodeWarrior project must have an extra file
called glue.c, which specifies each external subroutine. Each reference to
the external subroutine should have an entry as follows in the glue.c file:
long gLVSB<external subroutine name> = 'LVSB';
void <external subroutine name>(void);
asm void <external subroutine name>(void) {
move.l gLVSB<external subroutine name>, a0
jmp (a0)
}
(MPW Compiler) The makefile for a calling CIN is the same as described
in the Steps for Creating a CIN section of Chapter 1, CIN Overview,
except you use the optional subrNames directive to identify the
subroutines the CIN references. Specifically, if your code calls two
external subroutines, A and B, you need to have the following line in
the makefile code:
subrNames = A B
If you are using the Visual C IDE, follow the steps described in Steps for
Creating a CIN section of Chapter 1, CIN Overview, with the exception of
adding lvsb.obj instead of cin.obj to your project.
This command creates a makefile you can use to create the CIN.
The following is the C code for this external subroutine. Name it sum.c.
/*
* sum.c
*/
#include "extcode.h"
float64 LVSBMain(float64 *x, int32 n);
float64 LVSBMain(float64 *x, int32 n)
{
int32 i;
float64 sum;
sum = 0.0;
for (i=0; i<n; i++)
sum += *x++;
return sum;
}
Macintosh
(THINK C Compiler and CodeWarrior 68K Compiler) To make a subroutine
using the THINK or CodeWarrior 68K C Compiler, create a project
named sum or sum.µ, respectively, and add sum.c and LVSBLib to the
project. Do not include the CINLib file in your project. Set the options
in the Options... and Set Project Type dialog boxes as described in the
Steps for Creating a CIN section of Chapter 1, CIN Overview. After you
create sum.tmp, run lvsbutil.app and select the Subroutine option.
cinToolsDir = cinToolsDir:
Complete or partial pathname to the
LabVIEW cintools folder.
cinToolsDir = cinToolsDir
Complete or partial pathname to the
LabVIEW cintools directory.
This creates a file called Makefile. After executing lvmkmf, enter make,
which uses the makefile to create a file called sum.lsb. CINs and other
external subroutines can call this sum.lsb file.
Save the .c file for the CIN as calcmean.c. The following is a listing of
calcmean.c, with its CINRun routine filled in and the prototype for the
sum external routine added.
/*
* CIN source file
*/
#include "extcode.h"
/*
* typedefs
*/
typedef struct {
int32 dimSize;
float64 arg1[1];
} TD1;
typedef TD1 **TD1Hdl;
extern float64 sum(float64 *x, int32 n);
CIN MgErr CINRun(TD1Hdl xArray, float64 *mean);
CIN MgErr CINRun(TD1Hdl xArray, float64 *mean)
{
float64 *x, total;
int32 n;
x = (*xArray)–>arg1;
n = (*xArray)–>dimSize;
total = sum(x, n);
*mean = total/(float64)n;
return noErr;
}
CINRun calculates the mean using the external subroutine sum to calculate
the sum of the array. The external subroutine is declared with the keyword
extern so the code compiles even though the subroutine is not present.
Macintosh
(THINK C Compiler) The THINK C project must have an extra file called
glue.c which specifies each external subroutine. The reference to the
external subroutine sum should have an entry as follows in the glue.c file:
long gLVSBsum = 'LVSB';
void sum(void);
void sum(void) {
asm {
move.l gLVSBsum, a0
jmp(a0)
}
}
cinToolsDir = cinToolsDir:
Complete or partial pathname to the
LabVIEW cintools folder.
cinToolsDir = cinToolsDir
Complete or partial pathname to the
LabVIEW cintools directory.
(Microsoft Visual C IDE) Building CINs that use external subroutines is not
supported using Microsoft Visual C IDE. A possible alternative would be
to use a DLL instead of an external subroutine.
For this example, create a text file with the name meansubs. It should
contain a single line with the word sum.
You then create the makefile for this CIN using the following command:
lvmkmf -ext meansubs calcmean
This creates a file called Makefile. After executing lvmkmf, enter make,
which uses the makefile to create a file called calcmean.lsb. You can
load the calcmean.lsb file into the CIN.
Note For descriptions of specific manager functions, see the CIN Function Overview
section of the LabVIEW Online Reference, available by selecting Help»Online
Reference.
Introduction
External code modules have a large set of functions you can use to perform
simple and complex operations. These functions, organized into libraries
called managers, range from low-level byte manipulation to routines for
sorting data and managing memory. All manager routines described in this
chapter are platform-independent. If you use these routines, you can create
external code modules that will work on all platforms LabVIEW supports.
LabVIEW managers use data types that explicitly indicate their size.
For example, if a routine requires a 4-byte integer as a parameter, you
define the parameter as an int32. The managers define data types in terms
of the fundamental data types for each compiler. Thus, on one compiler, the
managers might define an int32 as an int, while on another compiler, the
managers might define an int32 as a long int. When writing external
code modules, use the manager data types instead of the host computer data
types, because your code will be more portable and have fewer errors.
Applications that manipulate files can use the functions in the file manager.
This set of routines supports basic file operations such as creating, opening,
and closing files, writing data to files, and reading data from files. In
addition, file manager routines allow you to create directories, determine
characteristics of files and directories, and copy files. File manager routines
use a LabVIEW data type for file pathnames (Paths) that provides a
platform-independent way of specifying a file or directory path. You can
translate a Path to and from a host platform’s conventional format for
describing a file pathname. See the File Manager section of the LabVIEW
Online Reference for more information.
Booleans
External code modules work with two kinds of Booleans—those existing
in LabVIEW block diagrams and those passing to and from manager
routines. The manager routines use a conventional form of Boolean, where
0 is FALSE and 1 is TRUE. This form of Boolean is called a Bool32, and
it is stored as a 32-bit value.
LabVIEW block diagrams store Boolean scalars as 8-bit values. The value
is 1 if the Boolean is TRUE, and 0 if the Boolean is FALSE. This form of
Boolean is called an LVBoolean.
Name Description
Bool32 32-bit integer, 1 if TRUE, 0 if FALSE
LVBoolean 8-bit integer, 1 if TRUE, 0 if FALSE
Numerics
The managers support 8-, 16-, and 32-bit signed and unsigned integers.
For floating-point numbers, LabVIEW supports the single (32-bit), double
(64-bit), and extended floating-point (at least 80-bit) data types. LabVIEW
supports complex numbers containing two floating-point numbers, with
different complex numeric types for each of the floating-point data types.
The following lists show the basic LabVIEW data types for numbers.
• Signed Integers
– int8 8-bit integer
– int16 16-bit integer
– int32 32-bit integer
• Unsigned Integers
– uInt8 8-bit unsigned integer
– uInt16 16-bit unsigned integer
– uInt32 32-bit unsigned integer
• Floating-Point Numbers
– float32 32-bit floating-point number
– float64 64-bit floating-point number
– floatExt extended-precision floating-point number
Complex Numbers
The complex data types are structures with two floating-point components,
re and im. As with floating-point numbers, complex numbers can have
32-bit, 64-bit, and extended-precision components. The following
segments of code give the type definitions for each of these complex
data types.
typedef struct {
float32 re, im;
} cmplx64;
typedef struct {
float64 re, im;
} cmplx128;
typedef struct {
floatExt re, im;
} cmplxExt;
Arrays
LabVIEW supports arrays of any of the basic data types described in
the Scalar Data Types section of this chapter. You can construct more
complicated data types using clusters, which can in turn contain scalars,
arrays, and other clusters.
The first four bytes of a LabVIEW array indicate the number of elements
in the array. The elements of the array follow the length field. Chapter 2,
CIN Parameter Passing, gives examples of how to manipulate arrays.
Strings
LabVIEW supports C-style strings and Pascal-style strings, a special
string data type you use for string parameters to external code modules
called LStr, and lists of strings. The support manager contains routines
for manipulating strings and converting them among the different
types of strings.
Paths (Path)
A path (short for pathname) specifies the location of a file or directory
in a computer’s file system. There is a separate LabVIEW data type for
a path (represented as Path), which the file manager defines in a
platform-independent manner. The actual data type for a path is private
to the file manager and subject to change. You create and manipulate
Paths using file manager routines.
Memory-Related Types
LabVIEW uses pointers and handles to reference dynamically allocated
memory. These data types are described in detail in the CIN Function
Overview section of the LabVIEW Online Reference and have the
following type definitions.
typedef uChar *UPtr;
typedef uChar **UHandle;
Constants
The managers define the following constant for use with external
code modules.
NULL 0(uInt32)
The following constants define the possible values of the Bool32 data type.
FALSE 0 (int32)
TRUE 1 (int32)
Memory Manager
This section describes the memory manager, a set of platform-independent
routines for allocating, manipulating, and deallocating memory from
external code modules.
Note For descriptions of specific memory manager functions, see the Memory
Manager section of the LabVIEW Online Reference, available by selecting
Help»Online Reference.
Memory Allocation
Applications use two types of memory allocation: static and dynamic.
Memory Zones
LabVIEW's memory manager interface has the ability to distinguish
between two distinct sections, called zones. LabVIEW uses the data space
(DS) zone only to hold VI execution data. LabVIEW uses the application
zone (AZ) to hold all other data. Most memory manager functions have
two corresponding routines, one for each of the two zones. Routines that
operate on the data space zone begin with DS and routines for the
application zone begin with AZ.
Currently, the two zones are actually one zone, but this may change in
future releases of LabVIEW; therefore, a CIN programmer should write
programs as if the two zones actually exist.
All data passed to or from a CIN is allocated in the DS zone except for
Paths, which use AZ handles. You should only use file manager functions
(not the AZ memory manager routines) to manipulate Paths. Thus, your
CINs should use the DS memory routines when working with parameters
passed from the block diagram. The only exceptions to this rule are handles
created using the SizeHandle function, which allocates handles in the
application zone. If you pass one of these handles to a CIN, your CIN
should use AZ routines to work with the handle.
You create a handle using XXNewHandle, with which you specify the
size of the memory block. You create a pointer using XXNewPtr.
XXNewHandleClr and XXNewPClr are variations that create the
memory block and set it to all zeros.
When you are finished with the handle or pointer, release it using
XXDisposeHandle or XXDisposePtr.
Simple Example
The following example code shows how you work with a pointer
to an int32.
int32 *myInt32P;
myInt32P = (int32 *)DSNewPtr(sizeof(int32));
*myInt32P = 5;
x = *myInt32P + 7;
...
DSDisposePtr(myInt32P);
The first line declares the variable myInt32P as a pointer to, or the address
of, a signed 32-bit integer. This does not actually allocate memory for the
int32; it creates memory for an address and associates the name
myInt32P with that address. The P at the end of the variable name is a
convention used in this example to indicate the variable is a pointer.
The second line creates a block of memory in the data space large enough
to hold a single signed 32-bit integer and sets myInt32P to refer to this
memory block.
The third line places the value 5 in the memory location to which
myInt32P refers. The * operator refers to the value in the address location.
The fourth line sets x equal to the value at address myInt32P plus 7.
The following code is the same example using handles instead of pointers.
int32 **myInt32H;
myInt32H =(int32**)DSNewHandle(sizeof(int32));
**myInt32H = 5;
x = **myInt32H + 7;
...
DSDisposeHandle(myInt32H);
The second line creates a block of memory in the data space large
enough to hold a single int32. DSNewHandle places the address of the
memory block as an entry in the master pointer list and returns the address
of the master pointer entry. Finally, this line sets myInt32H to refer to the
master pointer.
The third line places the value 5 in the memory location to which
myInt32H refers. Because myInt32H is a handle, you use the * operator
twice to get to the data.
The fourth line sets x equal to the value referenced by myInt32H plus 7.
This example shows only the simplest aspects of how to work with pointers
and handles in C. Other examples throughout this manual show different
aspects of using pointers and handles. Refer to a C manual for a list of other
operators you can use with pointers and a more detailed discussion of how
to work with pointers.
File Manager
The file manager supports routines for opening and creating files, reading
data from and writing data to files, and closing files. In addition, with these
routines you can manipulate the end-of-file mark of a file and position the
current read or write mark to an arbitrary position in the file. With other file
routines you can move, copy, and rename files, determine and set file
characteristics and delete files.
Note For descriptions of specific file manager functions, see the File Manager section
of the LabVIEW Online Reference, available by selecting Help»Online Reference.
The file manager contains a number of routines for directories. With these
routines you can create and delete directories. You can also determine and
set directory characteristics and obtain a list of a directory's contents.
LabVIEW supports concurrent access to the same file, so you can have a
file open for both reading and writing simultaneously. When you open a
file, you can indicate whether you want the file to be read from and written
to concurrently. You can also lock a range of the file, if you need to ensure
a range is nonvolatile at a given time.
Finally, the file manager provides many routines for manipulating paths
(short for pathnames) in a platform-independent manner. The file manager
supports the creation of path descriptions, which are either relative to a
specific location or absolute (the full path). With file manager routines you
can create and compare paths, determine characteristics of paths, and
convert a path between platform-specific descriptions and the
platform-independent form.
How you identify a target depends upon whether the target is an open or
closed file. If a target is a closed file or a directory, you specify the target
using the target’s path. The path describes the volume containing the target,
the directories between the top level and the target, and the target’s name.
If the target is an open file, you use a file descriptor to specify LabVIEW
should perform an operation on the open file. The file descriptor is an
identifier the file manager associates with the file when you open it.
When you close the file, the file manager dissociates the file descriptor
from the file.
Path Specifications
LabVIEW uses three different kinds of filepath specifications:
conventional, empty, and LabVIEW specifications, described below.
A path does not necessarily go from the top of the hierarchy down to the
target. You can often use a platform-specific tag in place of a name that
indicates the path should go up a level from the current location.
For instance, on a UNIX system, you specify the path of a file or directory
as a series of names separated by the slash ( / ) character. If the path is
an absolute path, you begin the specification with a slash. You can
indicate the path should move up a level using two periods in a row ( .. ).
Thus, the following path specifies a file README relative to the top level
of the file system.
/usr/home/gregg/myapps/README
On the PC, you represent the empty absolute path as an empty string.
It specifies the set of all volumes on the system. A period ( . ) represents
the empty relative path.
File Descriptors
When you open a file, LabVIEW returns a file descriptor associated
with the file. A file descriptor is a data type LabVIEW uses to identify
open files. All operations performed on an open file use the file
descriptor to identify the file.
A file descriptor is valid only while the file is open. If you close the file,
the file descriptor is no longer associated with the file. If you subsequently
open the file, the new file descriptor will most likely be different from the
file descriptor LabVIEW used previously.
File Refnums
In the file manager, LabVIEW accesses open files using file descriptors.
On the front panel and block diagram, however, LabVIEW accesses open
files through file refnums. A file refnum contains a file descriptor for use
by the file manager, and additional information used by LabVIEW.
LabVIEW specifies file refnums using the LVRefNum data type, the
exact structure of which is private to the file manager. If you want to
pass references to open files into or out of a CIN, use the functions in the
File Refnums, Manipulating topic of the Online Reference to convert file
refnums to file descriptors, and to convert file descriptors to file refnums.
Support Manager
The support manager is a collection of constants, macros, basic data
types, and functions that perform operations on strings and numbers.
The support manager also has functions for determining the current time
in a variety of formats.
Note This section gives only a brief overview of the support manager. For descriptions
of specific support manager functions, see the Support Manager section of the
LabVIEW Online Reference, available by selecting Help»Online Reference.
With the utility functions you can sort and search on arbitrary data types,
using quicksort and binary search algorithms.
Certain routines specify time as a data structure with the following form.
typedef struct {
int32 sec;/* 0:59 */
int32 min;/* 0:59 */
int32 hour;/* 0:23 */
int32 mday;/* day of the month, 1:31 */
int32 mon;/* month of the year, 1:12 */
int32 year;/* year, 1904:2040 */
int32 wday;/* day of the week, 1:7 for Sun:Sat */
int32 yday;/* day of year (julian date), 1:366 */
int32 isdst;/* 1 if daylight savings time */
} DateRec;
SPARCstations with Solaris 1.x come with the bundled C compiler (cc)
that is not ANSI-compliant. Because the cc compiler requires substantial
modification to the header files included with LabVIEW, National
Instruments does not recommend using this compiler for CIN development.
Please note LabVIEW for Solaris 1.x does not accept object files created
with the -g debugging flag turned on during compilation.
(HP and Concurrent) You can use the vendor-supplied compilers on
these platforms.
Why do I get garbage back from math functions such as atan2, pow,
ceil, floor, ldexp, frexp, modf, and fmod when using MPW C?
Include "Math.h" at the top of your .c file.
Why can't I link to the math functions (sin, cos, and so on) when
using THINK C?
Find the math.c and error.c functions that came with THINK C and
include them in the project. Be sure to also include "Math.h" in the .c file.
Then enable the 68881 options under THINK C preferences.
National Instruments has technical assistance through electronic, fax, and telephone systems to quickly
provide the information you need. Our electronic services include a bulletin board service, an FTP site,
a fax-on-demand system, and e-mail support. If you have a hardware or software problem, first try the
electronic support systems. If the information available on these systems does not answer your
questions, we offer fax and telephone support through our technical support centers, which are staffed
by applications engineers.
Electronic Services
Bulletin Board Support
National Instruments has BBS and FTP sites dedicated for 24-hour support with a collection of files
and documents to answer most common customer questions. From these sites, you can also download
the latest instrument drivers, updates, and example programs. For recorded instructions on how to use
the bulletin board and FTP services and for BBS automated information, call 512 795 6990. You can
access these services at:
United States: 512 794 5422
Up to 14,400 baud, 8 data bits, 1 stop bit, no parity
United Kingdom: 01635 551422
Up to 9,600 baud, 8 data bits, 1 stop bit, no parity
France: 01 48 65 15 59
Up to 9,600 baud, 8 data bits, 1 stop bit, no parity
FTP Support
To access our FTP site, log on to our Internet host, ftp.natinst.com, as anonymous and use
your Internet address, such as [email protected], as your password. The support files and
documents are located in the /support directories.
If you are using any National Instruments hardware or software products related to this problem,
include the configuration forms from their user manuals. Include additional pages if necessary.
Name __________________________________________________________________________
Company _______________________________________________________________________
Address ________________________________________________________________________
_______________________________________________________________________________
Fax ( ___ ) ________________Phone ( ___ ) __________________________________________
Computer brand____________ Model ___________________ Processor_____________________
Operating system (include version number) ____________________________________________
Clock speed ______MHz RAM _____MB Display adapter __________________________
Mouse ___yes ___no Other adapters installed _______________________________________
Hard disk capacity _____MB Brand_________________________________________________
Instruments used _________________________________________________________________
_______________________________________________________________________________
National Instruments hardware product model _____________ Revision ____________________
Configuration ___________________________________________________________________
National Instruments software product ___________________ Version _____________________
Configuration ___________________________________________________________________
The problem is: __________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
List any error messages: ___________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
The following steps reproduce the problem: ___________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
Documentation Comment Form
National Instruments encourages you to comment on the documentation supplied with our products.
This information helps us provide quality products to meet your needs.
Title: LabVIEW™ Code Interface Reference Manual
If you find errors in the manual, please record the page numbers and describe the errors.
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
Numbers/Symbols
1D One-dimensional.
2D Two-dimensional.
A
ANSI American National Standards Institute.
asynchronous execution Mode in which multiple processes share processor time, one executing
while the others, for example, wait for interrupts, as while performing
device I/O or waiting for a clock tick.
AZ (application zone) Memory allocation section that holds all data in a VI except execution data.
B
block diagram Pictorial description or representation of a program or algorithm. In
LabVIEW, the block diagram, which consists of executable icons called
nodes and wires that carry data between the nodes, is the source code for
the virtual instrument. The block diagram resides in the block diagram of
the VI.
Boolean controls and Front panel objects used to manipulate and display or input and output
indicators Boolean (True or False) data. Several styles are available, such as switches,
buttons and LEDs.
breakpoint Mode that halts execution when a subVI is called. You set a breakpoint by
clicking on the toolbar and then on a node.
broken VI VI that cannot be compiled or run; signified by a run button with a broken
arrow.
Bundle node Function that creates clusters from various types of elements.
C
C string (CStr) A series of zero or more unsigned characters, terminated by a zero, used in
the C programming language.
Case Structure Conditional branching control structure, which executes one and only one
of its subdiagrams based on its input. It is the combination of the IF THEN
ELSE and CASE statements in control flow languages.
cast To change the type descriptor of a data element without altering the
memory image of the data.
CIN source code Original, uncompiled text code. See object code.
cluster A set of ordered, unindexed data elements of any data type including
numeric, Boolean, string, array, or cluster. The elements must be all
controls or all indicators.
Code Interface Node Special block diagram node through which you can link conventional,
text-based code to a VI.
code resource Resource containing executable machine code. You link code resources to
LabVIEW through a CIN.
concatenated Pascal A list of Pascal-type strings concatenated into a single block of memory.
string (CPStr)
connector Part of the VI or function node containing its input and output terminals,
through which data passes to and from the node.
D
data acquisition Process of acquiring data, typically from A/D or digital input plug-in
boards.
data type descriptor Code that identifies data types, used in data storage and representation.
DS (data space) zone Memory allocation section that holds VI execution data.
E
empty array Array that has zero elements, but has a defined data type. For example,
an array that has a numeric control in its data display window but has
no defined values for any element is an empty numeric array.
EOF End-of-file. Character offset of the end of file relative to the beginning of
the file (the EOF is the size of the file).
F
flattened data Data of any type that has been converted to a string, usually for writing it
to a file.
Formula Node Node that executes formulas you enter as text. Especially useful for lengthy
formulas too cumbersome to build in block diagram form.
G
G LabVIEW graphical programming language.
H
handle Pointer to a pointer to a block of memory; handles reference arrays and
strings. An array of strings is a handle to a block of memory containing
handles to strings.
I
icon Graphical representation of a node on a block diagram.
icon pane Region in the upper right-hand corner of the front panel and block diagram
windows that displays the VI icon.
inplace Characteristic of an operation whose input and output data can use the same
memory space.
L
LabVIEW string (LStr) The string data type used by LabVIEW block diagrams.
M
matrix Two-dimensional array.
MB Megabytes of memory.
N
NaN Digital display value for a floating-point representation of not-a-number,
typically the result of an undefined operation, such as log(–1).
O
object Generic term for any item on the front panel or block diagram, including
controls, nodes, wires, and imported pictures.
object code Compiled version of source code. Object code is not stand-alone because
you must load it into LabVIEW to run it.
P
Pascal string (PStr) A series of unsigned characters, with the value of the first character
indicating the length of the string. Used in the Pascal programming
language.
pop up To call up a special menu by clicking on an object with the right mouse
button (Windows, Sun and HP-UX) or holding down the <command> key
while clicking (Macintosh).
pop-up menus Menus accessed by popping up on an object. Menu options pertain to that
object specifically.
private data structures Data structures whose exact format is not described and is usually subject
to change.
R
RAM Random Access Memory.
reentrant execution Mode in which calls to multiple instances of a subVI can execute in parallel
with distinct and separate data storage.
representation Subtype of the numeric data type, of which there are signed and unsigned
byte, word, and long integers, as well as single-, double-, and
extended-precision floating-point numbers both real and complex.
S
scalar Number capable of being represented by a point on a scale. A single value
as opposed to an array. Scalar Booleans, strings and clusters are explicitly
singular instances of their respective data types.
shared external routine Subroutine that can be shared by several CIN code resources.
sink terminal Terminal that absorbs data. Also called a destination terminal.
T
terminal Object or region on a node through which data passes.
top-level VI VI at the top of the VI hierarchy. This term is used to distinguish the VI
from its subVIs.
V
vector One-dimensional array.
virtual instrument (VI) LabVIEW program; so called because it models the appearance of a
physical instrument.
W
wire Data path between nodes.