National Instruments 320685D-01 User Manual

LabWindows/CVI Programmer Reference Manual

LabWindows/CVI Programmer Reference Manual
February 1998 Edition
Part Number 320685D-01

Internet Support

Bulletin Board Support

BBS United States: 51 2 794 5422 BBS United Kingd om: 01635 551422 BBS France: 01 48 65 15 59

Fax-on-Demand Support

512 418 1111

Telephone Support (USA)

Tel: 512 795 8248 Fax: 512 794 5678

International Offices

Australia 03 9879 5166, Austria 0662 45 79 90 0, Belgium 02 757 00 20, Brazil 0 11 288 333 6, 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, Kore a 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

National Instruments Corporate Headquarters

6504 Bridge Point Parkway Austin, Texas 78730 -5039 USA Tel: 512 794 0100
© Copyright 1994, 1998 National Instruments Corporation. All rights reserved.

Important Information

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 accept ed for warranty work. National Instru ments will pay the shippi ng costs of returning to the owner parts which are covered by warranty.
National Instruments believes that the informatio n in this manual is accurate. The docume nt has been ca refully review ed for technical accurac y. In th e even t that te ch nical o r typograp hic al errors exis t, Nation al Inst ruments rese rves th e 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.
XCEPT AS SPECIFIED HEREIN
E
ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE BY FAULT OR NEGLIGENCE ON THE PART OF NATIONAL INSTRUMENTS SHALL BE LIMITED TO THE AMOUNT THERETOFORE PAID BY THE CUSTOME R OR INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY THEREOF
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.
ATIONAL INSTRUMENTS WILL NOT BE LIABLE FOR DAMAGES RESULTING FROM LOSS OF DATA, PROFITS, USE OF PRODUCTS
. N
ATIONAL INSTRUMENTS MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AND SPECIFICALLY DISCLAIMS
, N

Copyright

Under the copyright laws, this publication may not be reproduced or transmitted in any form, electronic or mechanical, including photocopyi ng, recordi ng, st oring in an info rmation ret riev al syste m, or translating , in whole or in part, wit hout the prior written consent of National Instruments Corporation.
USTOMER’S RIGHT TO RECOVER DAMAGES CAUSED
. C
. This limitation of the liability of
,

Trademarks

CVI™, National Instruments™, the National Instruments logo, natinst.com™, and The Software is the Instrument™are trademarks of National Instruments Corporation.
Product and company names listed are trademarks or trade names of their respective companies.
WARNING REGARDING MEDICAL AND CLINICAL USE OF NATIONAL INSTRUMENTS PRODUCTS
National Instruments products are not designed with components and testing intended to ensure a level of reliability suitable for use in treatment and diagnosis of humans. Applications of National Instruments products involving medical or clinical treatment can create a potential for accidental injury caused by product failure, or by errors on the part of the user or application des igner. Any us e or ap plica tion of Na tiona l Instrum ents pr oducts for or inv olving m edi cal or clin ica l treatment must be performed by properly trai ned and qualifi ed medic al pe rsonne l, and al l tra ditiona l medic al safegu ards, equipment, and procedu res that are appropriate in the particula r situation to prevent serious injury or dea th should al ways continue to be used when Natio nal Instrume nts products are being use d. National In struments prod ucts are N OT intended to be a substitute for any form of establis hed process, procedure, or e quipment us ed to monit or or safeguard human heal th and safety in medical or clinical treatment.

Contents

About This Manual
Organization of This Manual................................................ ...... ..... ................................xiii
Conventions Used in This Manual...................................................................................xiv
Related Documentation.....................................................................................xv
Customer Communication.............................................................................. ...xvi
Chapter 1 LabWindows/CVI Compiler
Overview.......................................................................................................................... 1-1
LabWindows/CVI Compiler Specifics............................................................................1-1
Compiler Limits................................................................................................. 1-1
Compiler Options..............................................................................................1-2
Compiler Defines............................................................................................... 1-2
C Language Non-Conformance.......................................................................................1-2
C Language Extensions ...................................................................................................1-2
Keywords That Are Not ANSI C Standard.......................................................1-2
Calling Conventions (Windows 95/NT Only)...................................................1-2
Import and Export Qualifiers.............................................................................1-3
C++ Comment Markers.....................................................................................1-4
Duplicate Typedefs........................................................................ ..... ...............1-4
Structure Packing Pragma (Windows 3.1 and Windows 95/NT Only).............1-4
Program Entry Points (Windows 95/NT Only) .................................................1-5
C Library Issues...............................................................................................................1-5
Using the Low-Level I/O Functions..................................................................1-5
C Data Types and 32-Bit Compiler Issues.......................................................................1-6
Data Types.........................................................................................................1-6
Converting 16-Bit Source Code to 32-Bit Source Code ...................................1-6
Debugging Levels............................................................................................................1-8
User Protection ................................................................................................................1-8
Array Indexing and Pointer Protection Errors...................................................1-8
Pointer Arithmetic (Non-Fatal)...........................................................1-8
Pointer Assignment (Non-Fatal).........................................................1-9
Pointer Dereference Errors (Fatal)......................................................1-9
Pointer Comparison (Non-Fatal).........................................................1-10
Pointer Subtraction (Non-Fatal)..........................................................1-10
Pointer Casting (Non-Fatal)................................................................1-10
Dynamic Memory Protection Errors.................................................................1-11
Memory Deallocation (Non-Fatal)......................................................1-11
Memory Corruption (Fatal)............................................. ....................1-11
©
National Instruments Corporation v LabWindows/CVI Programmer Reference Manual
Contents
General Protection Errors..................................................................................1-11
Library Protection Errors..................................................................................1-11
Disabling User Protection..................................................... ...... ......................1-12
Disabling Protection Errors at Run-Time...........................................1-12
Disabling Library Errors at Run-Time...............................................1-12
Disabling Protection for Individual Pointer........................................1-12
Disabling Library Protection Errors for Functions.............................1-13
Details of User Protection.................................................................................1-14
Pointer Casting ...................................................................................1-14
Dynamic Memory...............................................................................1-15
Avoid Unassigned Dynamic Allocation in
Function Parameters..........................................................1-15
Library Functions ......................................................... ...... ..... ...........1-16
Unions................................................................................. ..... ...... .....1-16
Stack Size ........................................................................................................................1-16
Include Paths ...................................................................................................................1-17
Include Path Search Precedence .......................................................................1-17
Chapter 2 Using Loadable Compiled Modules
About Loadable Compiled Modules ...............................................................................2-1
Advantages and Disadvantages of Using Loadable Compiled Modules
in LabWindows/CVI......................................................................................2-2
Using a Loadable Compiled Module as an Instrument Driver
Program F ile...................................................................................................2-2
Using a Loadable Compiled Module as a User Library....................................2-3
Using a Loadable Compiled Module in the Project List...................................2-3
Using a Loadable Compiled Module as an External Module...........................2-4
Notification of Changes in Run State ...............................................................2-4
Example 1...........................................................................................2-5
Example 2...........................................................................................2-6
Using Run State Change Callbacks in a DLL...................................................2-6
Compiled Modules that Contain Asynchronous Callbacks ..............................2-7
Chapter 3 Windows 95/NT Compiler/Linker Issues
Loading 32-Bit DLLs under Windows 95/NT ................................................................3-1
DLLs for Instrument Drivers and User Libraries..............................................3-2
Using The LoadExternalModule Function .......................................................3-2
Link Errors when Using DLL Import Libraries................................................3-2
DLL Path (.pth) Files Not Supported................................................................3-2
16-Bit DLLs Not Supported..............................................................................3-2
LabWindows/CVI Programmer Reference Manual vi
©
National Instruments Corporation
Contents
Run State Change Callbacks in DLLs ...............................................................3-2
DllMain..............................................................................................................3-3
Releasing Resources when a DLL Unloads......................................................3-3
Generating an Import Library............................................................................3-4
Default Unloading/Reloading Policy ................................................................3-4
Compatibility with External Compilers ...........................................................................3-4
Choosing Your Compatible Compiler...............................................................3-5
Object Files, Library Files, and DLL Import Libraries.....................................3-5
Compatibility Issues in DLLs............................................................................3-5
Structure Packing................................................................................3-6
Bit Fields.................................................................................... ...... ...3-6
Returning Floats and Doubles.............................................................3-7
Returning Structures ...........................................................................3-7
Enum Sizes..........................................................................................3-7
Long Doubles...................................... ................................. ...... .........3-7
Differences between LabWindows/CVI and the External Compilers...............3-7
External Compiler Versions Supported.............................................................3-8
Required Preprocessor Definitions....................................................................3-8
Multithreading and the LabWindows/CVI Libraries.......................................................3-8
Using LabWindows/CVI Libraries in External Compilers..............................................3-9
Include Files for the ANSI C Library and the LabWindows/CVI
Libraries..........................................................................................................3-10
Standard Input/Output Window ........................................................................3-10
Resolving Callback References from .UIR Files ..............................................3-10
Linking to Callback Functions Not Exported from a DLL.................3-11
Resolving References from Modules Loaded at Run-Time..............................3-12
Resolving References to the LabWindows/CVI
Run-Time Engine.............................................................................3-12
Resolving References to Symbols Not in Run-Time Engine..............3-12
Resolving Run-Time Module References to Symbols
Not Exported from a DLL...................................... ..........................3-13
Run State Change Callbacks Are Not Available in External Compilers...........3-13
Calling InitCVIRTE and CloseCVIRTE...........................................................3-14
Watcom Stack Based Calling Convention ........................................................3-15
Using Object and Library Files in External Compilers...................................................3-15
Default Library Directives.................................................................................3-15
Microsoft Visual C/C++ .....................................................................3-16
Borland C/C++....................................................................................3-16
Watcom C/C++...................................................................................3-16
Symantec C/C++.................................................................................3-16
Borland Static versus Dynamic C Libraries......................................................3-17
Borland Incremental Linker ..............................................................................3-17
©
National Instruments Corporation vii LabWindows/CVI Programmer Reference Manual
Contents
Borland C++ Builder.........................................................................................3-17
Watcom Pull-in References ..............................................................................3-17
Creating Object and Library Files in External Compilers for Use
in LabWindows/CVI.....................................................................................................3-18
Microsoft Visual C/C++ ...................................................................................3-18
Borland C/C++..................................................................................................3-18
Watcom C/C++.................................................................................................3-19
Symantec C/C++...............................................................................................3-19
Creating Executables in LabWindows/CVI....................................................................3-20
Creating DLLs in LabWindows/CVI..............................................................................3-20
Customizing an Import Library.........................................................................3-20
Preparing Source Code for Use in a DLL.........................................................3-21
Calling Convention for Exported Functions.......................................3-21
Exporting DLL Functions and Variables............................................3-22
Include File Method............................................................................3-22
Export Qualifier Method ....................................................................3-22
Marking Imported Symbols in Include File Distributed
with DLL .........................................................................................3-23
Recommendations ..............................................................................3-24
Automatic Inclusion of Type Library Resource for Visual Basic .................... 3-24
Creating Static Libraries in LabWindows/CVI................... ..... ...... .................................3-25
Creating Object Files in LabWindows/CVI....................................................................3-26
Calling Windows SDK Functions in LabWindows/CVI.................................................3-26
Windows SDK Include Files.............................................................................3-26
Using Windows SDK Functions for User Interface Capabilities .....................3-27
Using Windows SDK Functions to Create Multiple Threads...........................3-27
Automatic Loading of SDK Import Libraries...................................................3-27
Setting Up Include Paths for LabWindows/CVI, ANSI C, and SDK Libraries.............. 3-28
Compiling in LabWindows/CVI for Linking in LabWindows/CVI.................3-28
Compiling in LabWindows/CVI for Linking in an External Compiler............ 3-28
Compiling in an External Compiler for Linking in an External Compiler....... 3-28
Compiling in an External Compiler for Linking in LabWindows/CVI............ 3-29
Handling Hardware Interrupts under Windows 95/NT...................................................3-29
Chapter 4 Windows 3.1 Compiler/Linker Issues
Using Modules Compiled by LabWindows/CVI............................................................4-1
Using 32-Bit Watcom Compiled Modules under Windows 3.1......................................4-1
Using 32-Bit Borland or Symantec Compiled Modules under Windows 3.1 .................4-2
16-Bit Windows DLLs........................... ...... ...... ................................. ...... ......................4-3
Helpful LabWindows/CVI Options for Working with DLLs...........................4-4
DLL Rules and Restrictions..............................................................................4-4
LabWindows/CVI Programmer Reference Manual viii
©
National Instruments Corporation
DLL Glue Code............... ..... ...... .................................. ..... ...... ..........................4-7
DLLs That Can Use Glue Code Generated at Load Time..................4-8
DLLs That Cannot Use Glue Code Generated at Load Time.............4-8
Loading a DLL That Cannot Use Glue Code Generated
at Load Time ....................................................................................4-8
Rules for the DLL Include File Used to
Generate Glue Source........................................................4-9
If the DLL Requires a Support Module outside the DLL.....4-9
If You Pass Arrays Bigger Than 64 K to the DLL...............4-9
If the DLL Retains a Buffer after the Function Returns
(an Asynchronous Operation)............................................4-11
If the DLL Calls Directly Back into 32-Bit Code ................4-12
If the DLL Returns Pointers .................................................4-15
If a DLL Receives a Pointer that Points to Other
Pointers ..............................................................................4-18
DLL Exports Functions by Ordinal Value Only .................. 4-20
Recognizing Windows Messages Passed from a DLL......................................4-21
Creating 16-bit DLLs with Microsoft Visual C++ 1.5......................................4-21
Creating 16-bit DLLs with Borland C++ ...................................... ....................4-22
DLL Search Precedence.............................. ...... ..... .................................. ...... ...4-23
Chapter 5 UNIX Compiler/Linker Issues
Calling Sun C Library Functions.....................................................................................5-1
Restrictions on Calling Sun C Library Functions..............................................5-1
Using Shared Libraries in LabWindows/CVI..................................................................5-2
Using dlopen......................................................................................................5-2
The LabWindows/CVI Run-Time Engine as a Shared Library.......................................5-2
Creating Executables that Use the LabWindows/CVI Libraries .....................................5-3
Compatible External Compilers........................................................................5-3
Static and Shared Versions of the ANSI C and Other Sun Libraries................5-3
Non-ANSI Behavior of Sun Solaris 1 ANSI C Library....................................5-4
LabWindows/CVI Implements printf and scanf................................................5-4
Main Function Must Call InitCVIRTE.............................. ................................5-4
Run State Change Callbacks Are Not Available in Executables ......................5-5
Using Externally Compiled Modules ..............................................................................5-6
Restrictions on Externally Compiled Modules.............................. ..... ...............5-6
Compiling Modules With External Compilers..................................................5-6
Locking Process Segments into Memory Using plock() .................................................5-7
UNIX Asynchronous Signal Handling............................................................................5-7
Contents
©
National Instruments Corporation ix LabWindows/CVI Programmer Reference Manual
Contents
Solaris 1 ANSI C Library Implementation......................................................................5-8
Replacement Functions.................................................... .................................5-9
Additional Functions Not Found in Sun Solaris 1 libc.....................................5-9
Incompatibilities among LabWindows/CVI, Sun Solaris, and ANSI C ......................... 5-10
Between LabWindows/CVI and ANSI C .........................................................5-10
Between LabWindows/CVI and Sun Solaris....................................................5-11
Chapter 6 Building Multiplatform Applications
Multiplatform Programming Guidelines.........................................................................6-1
Library Issues....................................................................................................6-1
Externally Compiled Modules..........................................................................6-3
Multiplatform User Interface Guidelines........................................................................6-3
Chapter 7 Creating and Distributing Standalone Executables and DLLs
Introduction to the Run-Time Engine..............................................................................7-1
Distributing Standalone Executables under Windows......................................7-1
Minimum System Requirements for Windows 95/NT.......................7-1
No Math Coprocessor Required for Windows 95/NT........................7-2
Minimum System Requirements for Windows 3.1............................7-2
Math Coprocessor Software Emulation for Windows 3.1.................. 7-2
Distributing Standalone Executables under UNIX...........................................7-2
Distributing Standalone Executables under Solaris 2.........................7-3
Distributing Standalone Executables under Solaris 1.........................7-4
Minimum System Requirements for UNIX........................................7-5
Translating the Message File............................................................................7-5
Configuring the Run-Time Engine..................................................................................7-5
Solaris 1 Patches Required for Running Standalone Executable......................7-5
Configuration Option Descriptions...................................................................7-6
cvirtx (Windows 3.1 Only).................................................................7-6
cvidir (Windows Only).......................................................................7-7
useDefaultTimer (Windows Only).....................................................7-7
DSTRules............................................................................................7-7
UNIX Options.....................................................................................7-7
Necessary Files for Running Executable Programs........................................................7-8
Necessary Files for Using DLLs Created in Windows 95/NT........................................7-9
Location of Files on the Target Machine for Running Executables and DLLs...............7-9
LabWindows/CVI Run-Time Engine under Windows 95/NT ......................... 7-10
Run-Time Library DLLs ....................................................................7-10
Low-Level Support Driver .................................................................7-10
LabWindows/CVI Programmer Reference Manual x
©
National Instruments Corporation
Message, Resource, and Font Files............................................ ...... ...7-11
National Instruments Hardware I/O Libraries....................................7-11
LabWindows/CVI Run-Time Engine under Windows 3.1...............................7-11
LabWindows/CVI Run-Time Engine under Sun Solaris ..................................7-12
Rules for Accessing UIR, Image, and Panel State Files on All Platforms........7-12
Rules for Using DLL Files under Windows 95/NT.......................................... 7-13
Rules for Using DLL Files under Windows 3.1................................................7-13
Rules for Loading Files Using LoadExternalModule.......................................7-14
Forcing Modules that External Modules Refer to
into Your Executable or DLL ..........................................................7-15
Using LoadExternalModule on Files in the Project............................7-15
Using LoadExternalModule on Library and Object Files
Not in the Project .............................................................................7-16
Using LoadExternalModule on DLL Files under
Windows 95/NT...............................................................................7-17
Using LoadExternalModule on DLL and Path Files
under Windows 3.1 ..........................................................................7-17
Using LoadExternalModule on Source Files (.c)................................7-18
Rules for Accessing Other Files........................................................................7-19
Error Checking in Your Standalone Executable or DLL ..................................7-19
Chapter 8 Distributing Libraries and Function Panels
How to Distribute Libraries.............................................................................................8-1
Adding Libraries to User’s Library Menu.......................................................................8-1
Specifying Library Dependencies................................................................................. ...8-2
Contents
Chapter 9 Checking for Errors in LabWindows/CVI
Error Checking.................................................................................................................9-2
Status Reporting by LabWindows/CVI Libraries andInstrument Drivers......................9-3
User Interface Library.......................................................................................9-3
Analysis/Advanced Analysis Libraries.............................................................9-3
Easy I/O for DAQ Library.................................................................................9-4
Data Acquisition Library...................................................................................9-4
VXI Library.......................................................................................................9-4
GPIB/GPIB 488.2 Library.................................................................................9-4
RS-232 Library..................................................................................................9-5
VISA Library.....................................................................................................9-5
IVI Library.........................................................................................................9-5
TCP Library.......................................................................................................9-6
DDE Library......................................................................................................9-6
©
National Instruments Corporation xi LabWindows/CVI Programmer Reference Manual
Contents
ActiveX Automation Library............................................................................9-6
X Property Library............................................................................................9-6
Formatting and I/O Library...............................................................................9-6
Utility Library...................................................................................................9-7
ANSI C Library.................................................................................................9-7
LabWindows/CVI Instrument Drivers..............................................................9-7
Appendix A Errors and Warnings
Appendix B Customer Communication
Glossary

Figures

Figure 7-1. Files Necessary to Run a LabWindows/CVI Executable Program
on a Target Machine...........................................................................7-8

Tables

Table 1-1. LabWindows/CVI Compiler Limits .......................................................1-1
Table 1-2. LabWindows/CVI Allowable Data Types..............................................1-6
Table 1-3. Stack Size Ranges for LabWindows/CVI...............................................1-16
Table 7-1. LabWindows/CVI Run-Time Engine Files ............................................7-10
Table 7-2. Windows NT Registry Entry Values for the Low-Level
Support Driver....................................................................................7-11
Table 7-3. Pathnames and Targets of Links.............................................................7-12
Table A-1. Error Messages........................................................................................A-1
LabWindows/CVI Programmer Reference Manual xii
©
National Instruments Corporation

About This Manual

The LabWindows/CVI Programmer Reference Manual contains information to help you develop programs in LabWindows/CVI. The LabWindows/CVI Programmer Reference Manual is intended for use by LabWindows users who have already completed the Getting Started with LabWindows/CVI tutorial. To use this manual effectively, you should be familiar with Getting Started with LabW i ndows/CVI, the LabW indows/CVI User Manual, DOS, Windows, and the C programming language.

Organization of This Manual

The LabWindows/CVI Programmer Reference Manual is organized as follows:
Chapter 1, LabWindows/CVI Compiler, describes LabWindows/CVI
compiler specifics, C language extensions, 32-bit compiler issues, debugging levels, and user protection.
Chapter 2, Using Loadable Compiled Modules, describes the
advantages and disadv antages of using compiled code modules in your application. It also describes the kinds of compiled modules available in LabWindows/CVI and includes programming guidelines for modules you generate with external compilers.
Chapter 3, Windows 95/NT Compiler/Linker Issues, describes the
different kinds of compiled modules available under LabWindows/CVI for Wi nd ows 95/NT and includes programming guidelines for modules you generate with external compilers.
Chapter 4, Windows 3.1 Compiler/Linker Issues, describes the
different kinds of compiled modules available under LabWindows/CVI for Windows 3.1 and includes programming guidelines for modules you generate with external compilers.
Chapter 5, UNIX Compiler/Linker Issues, describes the kinds of
compiled modules available under LabWindows/CVI for UNIX and includes programming guidelines for modules you generate with external compilers.
Chapter 6, Buildin g Multiplatform Applications, contains guidelines
and caveats for writing platform-independent LabWindows/CVI applications. LabWindows/CVI currently runs under Windows 3.1 and Windows 95/NT for the PC, and Solaris 1 and Solaris 2 for the SPARCstation.
©
National Instruments Corporation xiii LabWindows/CVI Programmer Reference Manual
About This Manual
• Chapter7, Creating and Distributing Standalone Executables and
DLLs, describes how the LabWindows/CVI Run-time Engine, DLLs,
externally compiled modules, and other files interact with your executable file. This chapter also describes how to perform error checking in a standalone executable program. You can create executable programs from any project that runs in the LabWindows/CVI environment.
• Chapter8, Distributing Li braries andFuncti on Panels, describes how
to distribute libraries, add libraries to a user’s Library menu, and specify library dependencies.
• Chapter9, Checking for Errors in LabWindows/CVI, describes LabWindows/CVI error checking and how LabWindows/CVI reports errors in LabWindows/CVI libraries and compiled external modules.
•AppendixA, Errors and Warnings, contains an alphabetized list of compiler warnings, compiler errors, link errors, DLL loading errors, and external module loading errors generated by LabWindows/CVI.
•AppendixB, Customer Communication, contains forms to help you gather the information necessary to help us solve your technical problems and a form you can use to comment on the product documentation.
•The Glossary contains an alphabetical list of terms used in this manual and a description of each.
•The Index contains an alphabetical list of key terms and topics used in this manual, including the page where each one can be found.

Conventions Used in This Manual

The following conventions are used in this manual.
<> Angle brackets enclose the name of a key on the keyboard—for example,
<Shift>.
- A hyphen between two or more key names enclosed in angle brackets denotes that you should simult aneously press the na med keys—for example, <Ctrl-Alt-Delete>.
» The » symbol leads you through nest ed menu items and dial og box options
to a final action. The sequence File»Page Setup»Options» Substitute Fonts directs you to pull down the File menu, select the PageSetup item, select Options, and finally select the Substitute Fonts options from the last dialog box.
©
LabWindows/CVI Programmer Reference Manual xiv
National Instruments Corporation
About This Manual
This icon to the left of bold italicized text denotes a note, which alerts you to important information.
!
bold Bold text denotes the names of menus, menu items, parameters, or dialog
bold italic Bold italic text denotes an activity objective, note, caution, or warning.
italic Italic text denotes variables, emphasis, a cross reference, or an introduction
monospace Text in this font denotes text or characters that you should literally enter
monospace bold Bold text in this font denotes the messages and responses that the computer
monospace italic
paths Paths in this manual are denoted using backslashes (\) to separate drive
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.
box buttons.
to a key concept. This font also denotes text from which you supply the appropriate word or value.
from the keyboard, sections of code, programming examples, and syntax examples. This font is also used for the proper n ames of disk d ri ves, p aths, directories, programs, functions, filenames and extensions, and for statements and comments taken from programs.
automatically prints to the screen. Italic text in this font denotes that you must enter the appropriate words or
values in the place of these items.
names, director i es, fol ders, and files .

Related Documentation

You may find the following documentation helpful while programming in LabWindows/CVI:
Microsoft Developer Network CD, Microsoft Corporation, Redmond WA
Programmer’s Guide to Microsoft Windows 95, Microsoft Press, Redmond WA, 1995
Harbison, Samuel P. and Guy L. Steele, Jr., C: A Reference Manual, Englewood Cliffs, NJ: Prentice-Hall, Inc., 1995
©
National Instruments Corporation xv LabWindows/CVI Programmer Reference Manual
About This Manual

Customer Communication

National Instruments wants to recei v e you r comments on our p roducts and manuals. We are interested in the applications you develop with our products, and we want to help you if you have problems with the m. To make it easy for you to contact us, this manual contains comment and technical support forms for you to complete. These forms are in Appendix B, Customer Communication, at the end of this manual.
LabWindows/CVI Programmer Reference Manual xvi
©
National Instruments Corporation
LabWindows/CVI Compiler
This chapter describes LabWindows/CVI compiler specifics, C language extensions, 32-bit compiler issues, debugging levels, and user protection.

Overview

The LabWindows/CVI compiler is a 32-bit ANSI C compiler. The kernel of the LabWindo ws/CVI compiler is the lcc ANSI C compi ler (© Copyright 1990, 19 91, 1992, 1993 David R. Hanson). It is not an optimizing compiler, but instead focuses on debugging, user protection, and platform independence. Because the compiler is an integral part of the LabWindows/CVI en vironment and features a limited set of straightforward options, it is also easy to use.

LabWindows/CVI Compiler Specifics

This section describes specific LabWindows/CVI compiler limits, options, defines, and diversions from the ANSI C standar d.
1

Compiler Limits

Table 1-1 shows the compiler limits for LabWindows/CVI.
Table 1-1.
Coding Attribute Limit
Maximum nesting of #include 32 Maximum nesting of #if, #ifdef 16 Maximum number of macro parameters 32 Maximum number of function parameters 64 Maximum nesting of compound blocks 32 Maximum size of array/struct types 2
©
National Instruments Corporation 1-1 LabWindows/CVI Programmer Reference Manual
LabWindows/CVI Compiler Limits
31
Chapter 1 LabWindows/CVI Compiler

Compiler Options

Y ou can set the LabW indows/CVI compiler options by selecting Options»Compiler Opti ons in the Project window. This command opens a dialog box that allows you to set LabWindows/CVI compiler options. For a discussion of these options, refer to the Compiler Options section in Chapter 3, Project Window, of the LabWindows/CVI User Manual.

Compiler Defines

The LabWindows/CVI compiler accepts compiler defines through the Compiler Defines command in the Options menu of the Project window. For more information, refer to the
Compiler Defines section in Chapter 3, Project Window, of the LabWindows/CVI User Manual.

C Language Non-Conformance

LabWindows/CVI for UNIX does not allow you to pass a struct as one of a series of unspecified variable arguments. Because of this, LabWindows/CVI if
type is a struct type.
va_arg (ap, type) is not legal in
LabWindows/CVI accepts the
#line preprocessor directive, but ignores it.

C Language Extensions

The LabWindows/CVI compiler has several extensions to the C language. The purpose is to make the LabWindows/CVI compiler compatible with the commonly used C extensions in external compilers under Windows 95/NT.

Keywords That Are Not ANSI C Standard

LabWindows/CVI f or Windo ws 3.1 accepts the non-ANSI C keywords pascal, PASCAL, and
_pascal, but ignores them.

Calling Conventions (Windows 95/NT Only)

You can use the following calling convention qualifiers in function declarations:
cdecl _cdecl __cdecl _stdcall __stdcall
In Microsoft Visual C/C++, Borland C/C++, and Symantec C/C++, the calling convention normally defaults to __
(recommended)
(recommended)
cdecl if you do not use a calling convention qualifier. You can,
LabWindows/CVI Programmer Reference Manual 1-2
©
National Instruments Corporation
Chapter 1 LabWindows/CVI Compiler
however, set options to cause the calling convention to default to __stdcall. The behavior is the same in LabWindows/CVI. Y ou can set the default calling conv ention to either __
__stdcall using the Compiler Options command in the Options menu of the Project
or window. When you create a new project, the default calling convention is
__cdecl.
cdecl
In Watcom C/C++, the default calling convention is not __
-4s (80486 Stack-Based Calling) op tio n when you compil e a module in Watcom for
use the
cdecl or __stdcall. You must
use in LabWindows/CVI. Refer to the Compatibility with External Compilers section in Chapter 3, Windows 95/NT Compiler/Linker Issues. The
-4s option causes the stack-based
calling convention to be the default. In LabWindows/CVI under W atcom compatibility mode, the default calling con vention is always the stack-based con vention. It cannot be chan ged. The LabWindows/CVI compiler accepts the Watcom, except that floating point and structure return values do not work in the calling convention. National Instruments recommends that you avoid using
__cdecl and __stdcall conventions under
__cdecl
__cdecl with
Watcom.
__cdecl calling convention and the Watcom stack-based calling convention, the
In the calling function is responsible for cleaning up the stack. Functions can have a variable number of arguments.
__stdcall calling convention, the called function is responsible for cleaning up the
In the stack. Functions with a variable number of arguments do not work in
__stdcall qualifier on a function with a variable number of arguments,
the
__stdcall. If you use
LabWindows/CVI does not honor the qualifier. All compilers pass parameters and return values in the same way for
__stdcall functions, except for floating point and structure
return values. National Instruments recommends the
__stdcall calling convention for all functions
exported from a DLL, except functions with a variable number of arguments. Visual Basic and other non-C Windows programs expect DLL functions to be
__stdcall.

Import and Export Qualifiers

You can use the following qualifiers in variable and function declarations:
__declspec(dllimport) __declspec(dllexport) __import __export _import _export
©
National Instruments Corporation 1-3 LabWindows/CVI Programmer Reference Manual
Chapter 1 LabWindows/CVI Compiler
At this time, not all these qualifiers work in all external compilers. The LabWindows/CVI
cvidef.h include file defines the following macros, which are designed to work in each
external compiler.
DLLIMPORT DLLEXPORT
An import qualifier informs the compiler that the symbol is defined in a DLL. Declarations of variables imported from a DLL r equi r e import qualifiers , but function declarat i o ns do n ot .
An export qualifier is relevant only in a project for which the target type is Dynamic Link Library. The qualifier can be on the declaration or definition of the symbol, or both. The qualifier instructs the linker to include the symbol in the DLL import library.

C++ Comment Markers

You can use doub le slashes (/ /) to be gin a comment. The comment continues until the end of the line.

Duplicate Typedefs

The LabWindows/CVI compiler does not report an error on multiple definitions of the same typedef identifier, as long as the definitions are identical.
Structure Packing Pragma (Windows 3.1 and Windows 95/NT Only)
The pack pragma can be used within LabWindows/CVI to specify the m aximum alignment factor for elements within a structure. For exam ple, assume the following structur e definition:
struct t {
double d1; char charVal; short shortVal; double d2;
};
If the maximum alignment is 1, the compiler can start the structure on any 1-byte boundary and inserts no gaps between the structure elements.
If the maximum alignment is 8, the compiler must start the structure on an 8-byte boundary,
shortVal on a 2-byte boundary, and place d2 on an 8-byte boundary.
place
©
LabWindows/CVI Programmer Reference Manual 1-4
National Instruments Corporation
You can set the maximum alignment as follows:
#pragma pack(4) /* sets maximum alignment to 4 bytes */ #pragma pack(8) /* sets maximum alignment to 8 bytes */ #pragma pack() /* resets to the default*/
The maximum alignment the compiler applies to a structure is based on the last pack
pragma
statement it sees before the definition of the structure.

Program Entry Points (Windows 95/NT Only)

Under Windows 95/NT, you can u se WinMain instead of main as the entry-point function to your program. You might want to do this if you pl an to li nk your ex ecutable using an exte rnal compiler. You must include
WinMain parameter list. The following is the prototype for WinMain with the W indo ws data
windows.h for the data types that normally appear in the
types reduced to intrinsic C types.
int __stdcall WinMain(void * hInstance, void * hPrevInstance,
char * lpszCmdLine int nCmdShow)

C Library Issues

This section discusses special considerations in LabWindows/CVI in the areas of low-level I/O functions and the UNIX C library.
Chapter 1 LabWindows/CVI Compiler

Using the Low-Level I/O Functions

Many functions in the UNIX libraries and the C compiler libraries for the PC are not ANSI C Standard Library functions. In general, LabWindows/CVI implements the ANSI C Standard Library. Under UNIX, you can call UNIX libraries for the non-ANSI C functions in conjunction with LabWindows/CVI.
The low-level I/O functions ANSI C Standard Library . Under UNIX, these functions are av ailable in the UNIX C library . Refer to Chapter 5, UN IX Compiler /Linker Issues, for more information.
Under Windows, you can use these functions along with
lowlvlio.h.
©
National Instruments Corporation 1-5 LabWindows/CVI Programmer Reference Manual
open, close, read, write, lseek, and eof are not in the
sopen and fdopen if you include
Chapter 1 LabWindows/CVI Compiler

C Data Types and 32-Bit Compiler Issues

This section introduces the LabWindows/CVI compiler data types and discusses converting 16-bit source code to 32-bit source code.

Data Types

Table 1-2 shows the LabWindows/CVI allowable data types.
Table 1-2.
LabWindows/CVI Allowable Data Types
Type Size Minimum Maximum
char 8 –128 127 unsigned char 8 0 255 short 16 –32,768 32,767 unsigned short 16 0 65,535
int; long int 32 –2
31
231–1 unsigned int 32 0 232–1 unsigned long 32 0 232–1 float 32 –3.40282E+38 3.40282E+38
double; long double 64 –1.79769E+308 1.79769E+308
pointers (void *) 32 N/A N/A enum 8, 16, or 32 –2
31
231–1
The size of an enumeration type depends on the value of its enumeration constant. In LabWindo ws/CVI, characters are The types
float and double conform to 4-byte and 8-byte IEEE standard formats.
signed, unless you explicitly declare them unsigned.
Converting 16-Bit Source Code to 32-Bit Source Code
If you convert a LabWindows for DOS application to a LabWindows/CVI application, use this section as a guide after you complete the steps in Chapter 12, Converting LabWindows for DOS Applications, of the Getting Started with LabWindows/CVI manual.
In general, if you make few assumptions about the sizes of data types, little difference exists between a 16-bit compiler and a 32-bit compiler except for the lar ger capacity of integers and the larger address space for arrays and pointers.
LabWindows/CVI Programmer Reference Manual 1-6
©
National Instruments Corporation
Chapter 1 LabWindows/CVI Compiler
For example, the code
int x;
declares a 2-byte integer in a 16-bit compiler such as LabWindows for DOS. In contrast, a 32-bit compiler such as LabWindows/CVI handles this code as a declaration of a 4-byte integer. In most cases, this does not cause a problem and the conversion is transparent, because functions that use 2-byte integers in LabWindows for DOS use 4-byte integers in LabWindo ws/CVI. Howe ver , this con version does cause a problem when a prog ram performs one of the following actions:
Passes an array of 16-bit integers to a GPIB, VXI, or Data Acquisition (DAQ) function If you use a 32-bit
int array to receive a set of 16-bit integers from a device,
LabWindows/CVI packs two 16-bit values into each element of the 32-bit array. Any attempt to access the array on an element-by-element basis does not work. Declare the array as
short instead, and make sure any type specifiers that refer to it have the [b2]
modifier when you pass them as an argument to a Formatting and I/O Library function.
•Uses an For example, if yo u pass an
I/O Library, such as a
%i[b2] specifier, it does not work correctly. Remove the [b2] modifier, or declare the
variable as Conver sely , if you pass a
without the
int variable in a way that requires it to be a 2-byte integer
int argument by address to a function in the Formatting and
Scan source or a Scan/Fmt target, and it matches a %d[b2] or
short.
short argument by address and it matches a %d or %i specifier
[b2] modifier, it does not work correctly. Add the [b2] modifier.
Note The default for %d is 2 bytes on a 16-bi t compil er and 4 bytes on a 32-bi t compil er.
In the same way, the default for
int is 2 bytes on a 16-bit compiler, and 4 bytes on
a 32-bit compiler. This is why you do not have to make any m odifications if the specifier for a variable of type
int is %d without the b
All pointers are 32-bit offsets. LabWindows/CVI does not use the
n
modifier.
far pointers that have both
a segment selector and an offset, except in 16-bit Windows DLLs under Windows 3.1. LabWindows/CVI for Windows 3.1 calls 16-bit DLLs through a special interface LabWindo ws/CVI generates fro m the header file for the DLL. For more information, refer to the Using 32-Bit Watcom Compiled Mod ule s under Windows 3.1 and 16-Bit Windows DLLs sections in Chapter 4, Windows 3.1 Compiler/Linker Issues.
©
National Instruments Corporation 1-7 LabWindows/CVI Programmer Reference Manual
Chapter 1 LabWindows/CVI Compiler

Debugging Levels

Y o u can compile the source modules in your app lication to include debu gging information. If you do so, you can us e breakpo ints and view or modify v a riables and e xpres sions while y our program is suspended. You set the debugging level by selecting Options»Run Option s in the Project window. Refer to the Run Options section in Chapter 3, Project Window, of the LabWindows/CVI User Manual for information on debugging levels.

User Protection

User protection detects invalid program behavior that LabWindows/CVI cannot otherwise detect during compilation. LabWindows/CVI reports such invalid program behavior as user protection errors. When you set the debugging level to Standard or Extended, LabWindows/CVI maintains extra information for arrays, structures, and pointers, and uses the information at run time to determine the validity of addresses.
Two groups of user protection errors exist based upon two characteristics: severity level and error cate gory. In each case, the ANSI C standard states that programs with these errors have undefined behavior. The two severity levels are as follows:
Non-Fatal errors include expressions that are likely to cause problems, but do not directly affect program execution. Examples include b ad pointer ar ithmetic, attempts to free pointers more than once, and comparisons o f pointers to different ar ray objects. The expression is invalid and its behavior is undefined, but execution can continue.
Fatal errors include expressions that LabWindows/CVI cannot execute without causing major problems, such as causing a general protection fault. For example, dereferencing an invalid pointer value is a fatal error.
Error categories include pointer protection, dynamic memory protection, library protection, and general protection errors. Each of these categories includes subgroups as described in the following sections.

Array Indexing and Pointer Protection Errors

The pointer protection errors catch invalid operations with pointers and arrays. In this section, these errors are grouped by the type of expr ession that causes the error or the type of invalid pointer involved.
Pointer Arithmetic (Non-Fatal)
Pointer arithmetic expressions involve a pointer sub-expression and an integer sub-expression . LabWindows/CVI generates a n error when the pointer sub-expression is
LabWindows/CVI Programmer Reference Manual 1-8
©
National Instruments Corporation
Chapter 1 LabWindows/CVI Compiler
invalid or when the arithmetic operation results in an invalid pointer expression. The following user protection errors involve pointer arithmetic:
Pointer arithmetic involving u ninitialized pointer
Pointer arithmetic involving n ull pointer
Out-of-bounds pointer arithmetic (calculation of an array address that results in a pointer value either before the start, or past the end of the array)
Pointer arithmetic involving pointer to freed memory
Pointer arithmetic involving in valid pointer
Pointer arithmetic involving address of non-array object
Pointer arithmetic involving p ointer to function
Array index too large
Negative array index
Pointer Assignment (Non-Fatal)
LabWindows/CVI generates pointer assignment errors when you assign invalid values to pointer variables. These warnings can help determine when a particular pointer becomes invalid. The following user protection errors involve pointer assignment:
Assignment of uninitialized pointer value
Assignment of out-of-bounds pointer expression (assignment of an address before the start, or past the last element, of an array)
Assignment of pointer to freed memory
Assignment of invalid pointer expression
Pointer Dereference Errors (Fatal)
Dereferencing of inv alid pointer v alues is a fatal error because it can cause a memory f ault or other serious problem. The following user protection errors involve pointer dereferencing:
Dereference of uninitialized pointer
Dereference of null pointer
Dereference of out-of-bounds po inter (dereference using a pointer valu e before the start, or past the end, of an array)
Dereference of pointer to freed memory
Dereference of invalid pointer expression
Dereference of data pointer for use as a function
Dereference of function pointer for use as data
©
National Instruments Corporation 1-9 LabWindows/CVI Programmer Reference Manual
Chapter 1 LabWindows/CVI Compiler
Dereference of a pointer to an n-byte type where less than n bytes exist in the object
Dereference of unaligned pointer (UNIX only)
Pointer Comparison (Non-Fatal)
LabWindows/CVI generates pointer comparison errors for erroneous pointer comparison expressions. The following user protection errors involve pointer comparison:
Comparison involving uninitialized pointer
Comparison involving null pointer
Comparison involving invalid pointer
Comparison of pointers to different objects
Pointer comparison involving address of non-array object
Comparison of pointers to freed memory
Pointer Subtraction (Non-Fatal)
LabWindows/CVI generates pointer subtraction errors for erroneous pointer subtraction expressions. The following user protection errors involve pointer subtraction:
Subtraction involving unin itialized pointer
Subtraction involving null pointer
Subtraction involving invalid pointer
Subtraction of pointers to different objects
Pointer subtraction involving address of non-array object
Subtraction of pointers to freed memory
Pointer Casting (Non-Fatal)
LabWindows/CVI generates a pointer casting error when you cast a pointer expression to type
AnyType *) and not enough space exists for an object of type AnyType at the location the
( pointer expression specifi es. This occurs only when casting a dynamically allocated object fo r the first time, such as with the code LabWindows/CVI reports the following error:
expression to 'pointer to double'
LabWindows/CVI Programmer Reference Manual 1-10
(double *) malloc(1). In this example,
Not enough space for casting
.
©
National Instruments Corporation

Dynamic Memory Protection Errors

Dynamic memory protection errors report illegal operations with dyna mi c memory and corrupted dynamic memory during allocation and deallocation.
Memory Deallocation (Non-Fatal)
LabWindows/CVI generates memory deallocation errors when the pointer is not the result of a memory allocation. The following user protection errors involve memory deallocation:
Attempt to free uninitialized pointer
Attempt to free pointer to freed memory
Attempt to free invalid pointer expression
Attempt to free pointer not allocated with
Memory Corruption (Fatal)
LabWindows/CVI generates memory corruption errors when a memory allocation/deallocation detects corrupted memory. During each dynamic memory operation, LabWindows/CVI verifies the integrity of the memory blocks it uses in the operation. When you set the Debuggi ng Level to Exten ded, LabWindo ws/C VI thor oughl y checks al l dynami c memory on each memory oper ation. LabW in do ws/CVI generates the follo wing erro r when it discovers a problem:
Dynamic memory is corrupt.
Chapter 1 LabWindows/CVI Compiler
malloc or calloc

General Protection Errors

LabWindows/CVI also checks for stack overflow and missing return values:
Stack overflow (fatal)
Missing return value (non-fatal)
The missing return value error means that a non-void function (one you do not declare with
void return type) returned, but did not returned a value.

Library Protection Errors

Library functions sometimes generate errors when they receive invalid arguments. LabWindows/CVI error checking is sensitive to the requirements of each library function. The following errors involve library protection:
Null pointer argument to librar y function
Uninitialized pointer argument to library function
Passing a pointer to freed memory to a library function
Array argument too small
Passing by reference a scalar argument to a library function that expects an array
©
National Instruments Corporation 1-11 LabWindows/CVI Programmer Reference Manual
Chapter 1 LabWindows/CVI Compiler
Missing terminating null in string argument
Passing a string to a library function that expects a character reference parameter LabWindows/CVI libr ary functions retu rn error codes in a v ariety of cases. If you enable the
Break on Library Errors option in the Run Options command in the Options menu of the Project window , LabW indows/CVI suspends execution after a library function returns one of these errors. A message appears that displays the name of the function and either the return value or a string that explains why the function failed.

Disabling User Protection

Occasionally, you might want to disable user protection to avoid run-time errors that do not cause problems in your program.
Disabling Protection Errors at Run-Time
You can use the SetBreakOnProtectionErrors function in the Utility Library to programmatically control whether LabWindo ws/CVI suspends ex ecution when it encounters a protection error. This function does not affect the Break on Library Errors feature.
Disabling Library Errors at Run-Time
The Break on Library Errors option in the Run Options command in the Options m enu of the Project window lets you choose whether LabWindows/CVI suspends execution when a library function returns an error code. The option takes effect when you start executing the project. You can override the initial setting in your program by using the
SetBreakOnLibraryErrors function in the Utility Library. Use of this function does not
affect the reporting of other types of library protectio n errors.
Disabling Protection for Individual Pointer
You can disable pointer checking for a particular pointer by casting it first to an arithmetic type and then back to its original type, as shown in the following macro:
#define DISABLE_RUNTIME_CHECKING(ptr)((ptr) = (void *)
{
char *charPointer; /* run-time checking is performed for charPointer before this line */ DISABLE_RUNTIME_CHECKING(charPointer); /* no run-time checking is performed for charPointer after this line */
}
LabWindows/CVI Programmer Reference Manual 1-12
((unsigned)(ptr)))
©
National Instruments Corporation
Chapter 1 LabWindows/CVI Compiler
This macro could be useful in the following situation: LabWindows/CVI reports erroneous run-time errors because you set a pointer to d ynamic memory in a source module and you th en resize it in an object module. The following steps describe how this error occurs:
1. Y o u declare a pointer in a source module you compile with debu gging enabled. You then assign to the pointer an address that
AnyType *ptr; ptr = malloc(N);
malloc or calloc returns:
2. You reallocate the pointer in an object module so that it points to the same location in memory as before. This might occur if you call the and then reassign it to memory that you allocate with
ptr = realloc(ptr, M); /* M > N */
realloc function or free the pointer
malloc:
or
free(ptr); ptr = malloc(M);
3. You use the same pointer in a source module you compile with debugging enabled. At this point, LabWindows/CVI still expects the pointer to point to a block of memo ry of the original size
*(ptr+(M-1)) /* This generates a fatal run-time error, */
(N).
/* even though it is a legal expression. */
To prevent this error, use the DISABLE_RUNTIME_CHECKING macro to disable checking for the pointer after you allocate memory for it in the source module:
ptr = malloc(N); DISABLE_RUNTIME_CHECKING(ptr);
Disabling Library Protection Errors for Functions
You can disable or enable library protection errors by placing pragmas in the source code. LabWindo ws/CVI ignores t hese prag mas when y ou compil e without deb ugging informati on, that is, if the debugging level is None. For example, the following two pragmas enable and disable library checking for all the function declarations that occur after the pragma within a header or source file. The pragmas affect only the functions declared in the file in which the pragmas occur. These pragmas do not affect nested include files.
#pragma EnableLibraryRuntimeChecking #pragma DisableLibraryRuntimeChecking
The following pragmas enable and disable library checking for a particular function. You must declare the function before the occurrence of the pragma.
#pragma EnableFunctionRuntimeChecking function #pragma DisableFunctionRuntimeChecking function
©
National Instruments Corporation 1-13 LabWindows/CVI Programmer Reference Manual
Chapter 1 LabWindows/CVI Compiler
These two pragmas enable and disable run-time checking for a particular library function throughout the module in which they appear. You can use them to override the effects of the
EnableLibraryRuntimeChecking and DisableLibraryRuntimeChecking pragmas
for individual functions. If both of these pragmas occur in a module for the same function, LabWindows/CVI uses only the last occurrence.
Note These pragmas affect all protection, including run-time checking of function
arguments, for all calls to a specific library function. To disable breaking on errors for a particular call to a library function, use the Utility Library function
SetBreakOnLibraryErrors. To disable the run-time checking of argument
expressions for a particular ca ll to a library function, use the Utility Library function
Note You cannot use prag mas to disable protection for the functio ns in the
SetBreakOnProtectionErrors.
statically linked libraries including User Interface, RS-232, TCP, DDE, Formatting and I/O, Utility, X Property, and ANSI C libraries unless you place the
DisableLibraryRuntimeChecking pragma at the top of the library header file.

Details of User Protection

Pointer Casting
A cast expression consists of a left parenthesis, a type name, a right parenthesis, and an operand expression. The cast causes the compiler to convert the operand v alue to the type that appears within the parenthesis.
C programmers occasionally have to cast a pointer to one data type to a pointer to another data type. Because LabWindo ws/CVI does not restructure the user protection information for each cast expression, certain types of cast expressions implicitly disable run-time checking for the pointer value. In particular, casting a pointer expression to the following types disables run-time checking on the resulting value:
Pointer to a pointer:
(AnyType **) PointerExpression
Pointer to a structure:(struct AnyStruct *) PointerExpression
Pointer to an array:
(AnyType (*)[]) PointerExpression
Any non-pointer type:(unsigned) PointerExpression,
(int) PointerExpression, and so on
Note An exception exists. Casts that you apply implicitly or explicitly to the void *
values you obtain from
malloc or calloc do not disable user pro tecti o n.
Casting a pointer to one arithmetic type to a pointer to a different one, such as
(unsigned *), (short *), and so on, does not affect run-time checking on the resulting
pointer, nor does casting a pointer to a void pointer
LabWindows/CVI Programmer Reference Manual 1-14
(void *).
©
National Instruments Corporation
(int *),
Chapter 1 LabWindows/CVI Compiler
Dynamic Memory
LabWindows/CVI provides run-time error checking for pointers and arrays in dyna m ically allocated memory.
You can use the ANSI C library functions These functions return
void * values that you must cast to some other type before the
malloc or calloc to allocate dynamic memory.
memory can be used. During program execution, LabWindows/CVI uses the first such cast on the return value of each call to these functions to determine the type of the object that will be stored in the dynamic memory. Subsequent casts to different types can disable checking on the dynamic data, as explained in the Pointer Casting discussion in this section.
You can use the
realloc function to resize dynamically allocated memory. This function
increases or decreases the size of the object associated with the dynamic memory. LabWindows/CVI adjusts the user protection information accordingly.
Avoid Unassigned Dynamic Allocation in Function Parameters
The LabWindows/CVI run-time error checking mechanism dynamically allocates data to keep track of pointers that you dynamically allocate in your program. When you no longer use the pointers, LabWindows/CVI uses garbage collection to deallocate its corresponding dynamic memory.
A case exists where the garbage collection fails to retrieve all the memory it allocated. This occurs when you pass the return value of one function to another function, the return value is a pointer to dynamically allocated memory, and you do not assign the pointer to a variable in the argument expression. The following is an example:
MyFunc (1, 2, malloc(7));
This call passes the return value from malloc to MyFunc but does not assign it to a variable. If you make this call repeatedly in your program with run-time checki ng enabl ed, you lose a small amount of memory each time.
Change the code as follows to avoid this problem.
void *p; MyFunc (1, 2, p = malloc(7));
The following code also works and uses better programming style.
void *p; p = malloc(7); MyFunc (1, 2, p);
©
National Instruments Corporation 1-15 LabWindows/CVI Programmer Reference Manual
Chapter 1 LabWindows/CVI Compiler
Library Functions
The LabWindows/CVI library functions that take pointer arguments or that return pointers incorporate run-time checking f or those arguments and return values. Howe ver, yo u mu st be careful when passing arguments to library functions that have
GetCtrlAttribute and GetCtrlVal in the User Interface Library and memcpy and memset in the ANSI C library. If you use a void * cast when you pass an argument to a
function that expects a variably typed argument, you disable run-time checking for that argument. Some examples follow:
{
int value; GetCtrlVal(panel, ctrl, &value); /* CORRECT */
GetCtrlVal(panel, ctrl, (void *)&value);/* INCORRECT */ } {
char *names[N], *namesCopy[N];
memcpy(namesCopy, names, sizeof (names));/* CORRECT */
memcpy((void *)namesCopy, (void *)names, sizeof names);
}
void * parameters, such as
/* INCORRECT */
Unions
LabWindows/CVI performs only minimal checks for contains pointers, arrays, or structs, LabWindows/CVI does not maintain user protection information for those objects.

Stack Size

Your program uses the stack for passing function parameters and storing automatic local variables. You can set the maximum stack size by selecting the Options»Run Option s in the Project window. Table 1-3 shows the stack size ranges LabWindows/CVI supports.
Windows 3.1 4 KB 40 KB 40 KB Windows 95/NT 100 KB 250 KB 1 MB Solaris 1 for Sun 100 KB 250 KB 5 MB Solaris 2 for Sun 100 KB 250 KB 5 MB
union type variables. If a union
Table 1-3.
Stack Size Ranges for LabWindows/CVI
Platform Minimum Default Maximum
LabWindows/CVI Programmer Reference Manual 1-16
©
National Instruments Corporation
Chapter 1 LabWindows/CVI Compiler
Note For LabWindows/CVI for Windows 3.1, the actual stack size approaches 64 KB
when you set the Debugging level to None.

Include Paths

The Include Paths command in the Options menu of the Project window specifies the directory search path for include files. The Include Paths dialog box has two lists, one for include paths specific to the project, and one for paths not specific to the project.
When you install VXIplug&play instrument drivers, the installation program places the include files for the driv ers in a specif ic VXIplug&play include directory . LabWindo ws/CVI also searches that directory for include files.

Include Path Search Precedence

LabWindows/CVI searches for include files in the following locations and in the following order:
1. Project list
2. Project-specific include paths
3. Non-project-specific include paths
4. The paths listed in the Instru ment Directories dialog box
5. The subdirectories under the
6. The
7. The
8. The
9. The VXIplug&play include directory
10. The
cvi\instr directory cvi\include directory cvi\include\ansi directory
cvi\sdk\include directory (Windows 95/NT only)
cvi\toolslib directory
©
National Instruments Corporation 1-17 LabWindows/CVI Programmer Reference Manual
Using Loadable Compiled Modules
This chapter describes the advantages and disadv an tag es of using compiled code modules in your applicatio n. It also describes the kinds of compiled modules available in LabWindows/CVI and includes programming guidelines for modules you generate with external compilers.
Refer to Chapter 3, Windows 95/NT Compiler/Linker Issues, Chapter 4, Windows 3.1
Compiler/Linker Issues, or Chapter 5, UNIX Compiler/Linker Issues, in this manual for more
information on platform-specific programming guidelines for modules that external compilers generate.

About Loadable Compiled Modules

Several methods exist for using compiled modules in LabWindows/CVI. You can load compiled modules directly into the LabWindows/CVI environment as instrument driver programs or as user libraries, so they are accessible to any project. You can list compiled modules in your project, so they are accessible only within that project. You can use compiled modules dynamically in your program with
UnloadExternalModule. Any comp iled module you use in Lab W indo ws/CVI must b e
and in one of the following forms:
•A
.obj file on the PC, or a .o file under UNIX, that contains one object module
•A
.lib file on the PC, or a .a file under UNIX, that contains one or more object modu les
•A
.dll file that contains a Windows DLL (Windows only)
LoadExternalModule, RunExternalModule,
2
You can create any of these compiled modules in LabWindows/CVI under Windows 95/NT, or using a compatible external compiler. Under Windows 3.1, LabWindows/CVI can create
.obj files. Under UNIX, LabWindows/CVI can create only .o files.
only
©
National Instruments Corporation 2-1 LabWindows/CVI Programmer Reference Manual
Chapter 2 Using Loadable Compiled Modules
Advantages and Disadvantages of Using Loadable Compiled Modules inLabWindows/CVI
Using compiled modules in LabWindows/CVI has the following advantages:
• Compiled modules run faster than source modules. Compi led modules do not contain t he
debugging and user protection code LabWindows/CVI generates when it compiles
source modules. Compiled modules you generate in external compilers can run faster
because of optimization.
• LabWindows/CVI recompiles the source modules in a project each time you open the
project. Also, if an instrument driver pro gram file is a source modul e, LabWindows/CVI
recompiles it each time you load the instrument driver. LabWindows/CVI does not
recompile compiled modules when you open a project or load an instrument driver.
• In standalone executables, you can dynamically load compiled modules but not source
modules.
• You can install compiled modules, but not source modules, into the Library menu.
• You can provide libraries for other developers without giving them access to your source
code. Using compiled modules in LabWindows/CVI has the following disadvantages:
• You cannot debug compiled modules. Because compiled modules do not contain any
debugging information, you cannot set breakpoints or view variable values.
• Compiled modules do not include run-time error checking or user protection.
Using a Loadable Compiled Module as an Instrument Driver ProgramFile
An instrument driver is a set of high-level functions w ith graphical function panels to make programming easier. It encapsulates many low-level operations, such as data formatting and GPIB, RS-232, and VXI communication, into intuitive, high-level functions . An instrument driver usually controls a physical instrument, but it also can be a software utility. The Using
Instrument Drivers and Instrument Menu sections of Chapter 3, Project Window, of the LabWindows/CVI User Manual describe how to use instrument drivers.
To develop and debug an instrument driver, load its program file into LabWindows/CVI as a source file. After you finish debugging it, you can compile the program file into an object file or a Windows 95/NT DLL. The next time you load the instrument driver, LabWindows/CVI loads the compiled module, which loads and runs faster that the source module.
Refer to the LabWindows/CVI Instrument Driver Developers Guide for information on how to create an instrument driver.
©
LabWindows/CVI Programmer Reference Manual 2-2
National Instruments Corporation
Chapter 2 Using Loadable Compiled Modules
If the instrument driver program file is a compiled module, it must adhere to the requirements outlined for each operating system in Chapter 3, Windows 95/NT Compiler/Linker Issues, Chapter 4, Windows 3.1 Compiler/Linker Issues, and Chapter 5, UNIX Compiler/Linker
Issues, of this manual.
Using a Loadable Compiled Module as a User Library
You can install your own libraries into the Library menu. A user library has the same form as an instrument driver. You can load as a user library anything that you can load into the
Instrument menu, provided the progr am is in com pile d form. Refer t o the Using Instrument Drivers and the Instrument Menu sections of Chapter 3, Project Window, of the LabW indows /CVI Use r Manua l for more information. The main dif ference between modules
you load as instrument drivers and those you load as user libraries is that you can unload instrument drivers using the Unload command in the Instrument menu, but you cannot unload user libraries. You cannot edit and recompile user libraries while they are loaded.
Install user libraries by selecting the Library Options command in the Project Options menu. The next time you run LabWindows/CVI, the libraries load automatically and appear at the bottom of the Library menu.
You can de v e lop a user li brary mod ule to pro vi de sup port fu nction s for in stru ment drivers or any other modules in your project. By installing a module through the Library Options command, you ensure that the library is always available in the LabWindows/CVI developmen t environmen t. If you do not want to de velop function pan els for the library , create
.fp file without any classes or functions. In that case, LabWindows/CVI loads the library
a at startup but does not include the library name in th e Library menu.
User libraries must adhere to the requirements outlined for the target operating system. Chapter 3, Windows 95/NT Compiler/Linker Issues, Chapter 4, Windows 3.1
Compiler/Linker Issues, and Chapter 5, UNIX Compiler/Linker Issues, of this manual, discuss
operating system requirements.
Using a Loadable Compiled Module in the Project List
You can include compiled modules directly in the project list.
Note
Even when you inclu de a source module in the project list, you can instruct LabW indo ws/CVI to create an object module on disk when it compiles the file instead of debuggable code in memory. To do this, double click in the O column next to the source file in the Project window.
©
National Instruments Corporation 2-3 LabWindows/CVI Programmer Reference Manual
To use a DLL in your project under Windows 95/NT, you must include the DLL import library (
.lib) file in the project list rather than the DLL.
Chapter 2 Using Loadable Compiled Modules
Compiled modules must adhere to the requirements outlined for the target operating system. Chapter 3, Windows 95/NT Compiler/Linker Issues, Chapter 4, Windows 3.1
Compiler/Linker Issues, and Chapter 5, UNIX Compiler/Linker Issues, of this manual, discuss
operating system requirements.
Using a Loadable Compiled Module as an External Module
You can load a compiled module dynamically from your program. A module you load dynamically is called an external module. You can load, execute, and unload this external module programmaticall y us in g
UnloadExternalModule. Refer to Chapter 8, Utility Library, of the LabWindows/CVI
LoadExternalModule, GetExternalModuleAddr, and
Standard Libraries Reference Manual for more information on using these functions. While you develop and debug the external module, you can list it in the project as a source
file. After you finish debugging the module, you can compile it into an object file or a Windows 95/NT DLL. External modules must adhere to the requirements outlined for the target operating system. Chapter 3, Windows 95/NT Compiler/Linker Issues, Chapter 4,
Windows 3.1 Compiler/Linker Issues, and Chapter 5, UNIX Compiler/Linker Issues, of this
manual, discuss operating system requirements.

Notification of Changes in Run State

You migh t ha ve to no tify cert ain compile d modules whene v er your pr ogram starts , suspends, continues, or stops. For example, if a co mpiled module has asynchronous callbacks, yo u must prevent the callbacks from executing when program execution suspends at a breakpoint. LabWindows/CVI has a callback mechanism you can use to inform a compiled module of changes in the program status.
To notify a compiled module of changes in the run state, add a function with the name
__RunStateChangeCallback to the compiled module. LabWindows/CVI automatically
installs the callback for you. The run state change callback must be in a compiled file, not in a source file. More than one
compiled module can contain functions with this name, because LabWindows/CVI never enters it into the global name space. The prototype for the callback is as follows:
void CVICALLBACK __RunStateChangeCallback(int action)
libsupp.h defines the actions in the following enumerated type: enum {
kRunState_Start,
kRunState_Suspend,
kRunState_Resume,
kRunState_AbortingExecution,
kRunState_Stop,
LabWindows/CVI Programmer Reference Manual 2-4
©
National Instruments Corporation
Chapter 2 Using Loadable Compiled Modules
kRunState_EnableCallbacks, kRunState_DisableCallbacks
};
The following examples show typical program state changes.
Example 1
kRunState_Start kRunState_EnableCallbacks
/* user program execution begins */ . . .
/* a breakpoint or run-time error occurs, or user presses the
Terminate Execution key combination */ kRunState_DisableCallbacks kRunState_Suspend
/* program execution suspends; CVI environment resumes */ . . .
/* user requests the execution be resumed, through the "Continue",
"Step Over", etc., commands */ kRunState_Resume kRunState_EnableCallbacks
/* user program execution resumes */
.
.
.
/* user program execution completes normally */ kRunState_DisableCallbacks kRunState_Stop
©
National Instruments Corporation 2-5 LabWindows/CVI Programmer Reference Manual
Chapter 2 Using Loadable Compiled Modules
Example 2
kRunState_Start kRunState_EnableCallbacks
/* user program execution begins */ . . . /* a breakpoint or run-time error occurs, or user presses the
Terminate Execution key combination */ kRunState_DisableCallbacks kRunState_Suspend
/* program execution suspends; CVI environment resumes */
.
.
.
/* user selects the Terminate Execution command */ kRunState_DisableCallbacks /* even though callbacks already
kRunState_AbortingExecution
/* long jump out of user program */ kRunState_DisableCallbacks /* even though callbacks already
kRunState_Stop
disabled */
disabled */
Note
A Resume notification does not always follow a Suspend notification. A Stop notification can follow a
Suspend notification without an intervening Resume
notification.
Note
Run state change callbacks do no t work if you link your program in an external compiler. Also, external compilers report link errors if you have multiple run state change callbacks.

Using Run State Change Callbacks in a DLL

You can include one or more run state change callbacks in a DLL. To do so, you must build the DLL in the LabWindows/CVI development environment, and each run state change callback must be in a separate object or static library file in the DLL project. I f you include a run state change callback in a DLL, or in an object or s tatic library f ile that another user migh t include in a DLL, take special care in two areas:
Use caution when you call in to other DLLs in respo nse to a
When you use your DLL in a standalone executable, the DLL receives the
kRunState_Stop message when the executable terminates. The order in which
LabWindows/CVI Programmer Reference Manual 2-6
kRunState_Stop message.
©
National Instruments Corporation
Chapter 2 Using Loadable Compiled Modules
Windo ws 95/NT unlo ads DLLs at process termi nation is not well-d efined. Therefo re, the DLL you call into might no longer be loaded. This can cause a general protectio n fault.
Nevertheless, when you use your DLL in a program in the LabWindows/CVI development environment, it is often necessary to call into DLLs to release resources after each run. To solve this dilemma, use conditional code to release resources only if you are running in the LabWindows/CVI development environment. An example follows.
#include <utility.h> switch (runState)
{ case kRunState_Stop:
if (! InStandaloneExecutable())
{ /* call into other DLLs to release resources */ } /* release resources, including unloading DLLs */ break;
}
It is always safe to call into the LabW indo ws/CVI Run- time Engine in a run state change callback.
If your DLL uses global v ariables that can become stale after each prog ram e xecution in the LabWindows/CVI development environment, re-initialize the variables in response
kRunState_Start or kRunState_Stop message. For example, memory that
to the you allocate using L abWin dows/CVI ANSI C functions such as
malloc or calloc is no
longer valid when you restart your program. If your DLL h a s gl ob al variables th at point to allocated memory, set those pointers to
kRunState_Stop message.
or
NULL in response to the kRunState_Start
Compiled Modules that Contain Asynchronous Callbacks
A compiled module can call a source code function asynchronously. This can happen throu gh interrupts or signals. In Windows 95/NT, the compiled module can call the source code function from a thread other than the main thread. The call takes place asynchronously with respect to the normal execution of the source code in your program.
The execution and debugging system in the LabWindows/CVI development environment is not prepared to handle this asynchronous execution. Consequently, the compiled module must announce to LabWindows/CVI that it is calling asynchronously into source code. It does this by calling
ExitAsyncCallback ExitAsyncCallback have one parameter, which is a pointer to a buffer of size ASYNC_CALLBACK_ENV_SIZE. Yo u must pass the same buffer into ExitAsyncCallback
that you passed into definition of
libsupp.h.
in
©
National Instruments Corporation 2-7 LabWindows/CVI Programmer Reference Manual
EnterAsyncCallback before calling the function, and calling
after calling the function. EnterAsyncCallback and
EnterAsyncCallback because the buff er stores state information. The
ASYNC_CALLBACK_ENV_SIZE and the prototypes for these two functions are
Windows 95/NT Compiler/Linker Issues
This chapter describes the different kinds of compiled modules available under LabWindows/CVI for Wi n dows 95/NT and includes programming guidelines for modules you generate with ext ern al compi lers.
Under Windows 95/NT, the LabWindows/CVI compiler is compatible with four external 32-bit compilers: Microsoft Visual C/C++, Borland C/C++, Watcom C/C++, and Symantec C/C++. This manual refers to the four compilers as the compatible external compilers.
In LabWindows/CVI under Windows 95/NT, you can do the following:
Load 32-bit DLLs, through the standard import library mechanism
Create 32-bit DLLs and DLL import libraries
Create library files and object files
Call the LabWindows/CVI libraries from executables or DLLs created with any of the four compatible external compilers
Create object files, library files, and DLL import libraries that the compatible external compilers can use
Load object files, library files, and DLL import libraries created with any of the four compatible external compilers
Call Windows Software Development Kit (SDK) functions
3
This chapter discusses these capabilities.
Loading 32-Bit DLLs under Windows 95/NT
Under Windows 95/NT, LabWindows/CVI can load 32-bit DLLs. LabWindows/CVI links to DLLs through the standard 32-bit DLL import libraries that you generate when you create 32-bit DLLs with any of the compilers. Because LabW indo ws/CVI links to DLLs in this way, you cannot specify a DLL file directly in your project. You must specify the DLL import library file instead.
©
National Instruments Corporation 3-1 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues

DLLs for Instrument Drivers and User Libraries

Under Windo ws 9 5/NT, LabW in dows /CVI does not dir ectly associ ate DLLs with in strument drivers or user libraries. However, LabWindows/CVI can associate instrument drivers and user libraries with DLL import libraries. Each DLL must have a DLL import library ( file. In general, if the program for an instrumen t driver or user library is in the form of a DLL, you must place the DLL import library in the same directory as the function panel ( The DLL import library specifies the name of the DLL that LabWindows/CVI searches for using the standard Windows DLL search algorithm.
LabWindows/CVI makes an exception to facilitate using VXIplug&play instrument driver DLLs. When you install a VXIplug&play instrument driver, the installation program does not place the DLL import library in the same directory as the is in the VXIplug&play directory, LabWindows/CVI searches for an import library in the VXIplug&play library directory before it looks for a program file in the directory of
.fp file, unless you list the program file in the project.
the

Using The LoadExternalModule Function

When you use the LoadExternalModule function to load a DLL at run time, you must specify the pathname of the DLL import library, not the name of the DLL.
.lib)
.fp) file.
.fp file. If a .fp file

Link Errors when Using DLL Import Libraries

A DLL import library must not contain any references to symbols that the DLL does not export. If it does, LabWindows/CVI reports a link error. If you load the DLL using
LoadExternalModule, the GetExternalModuleAddr function reports an undefined
references ( import library. Refer to the Generating an Import Library discussion later in this section.
–5) error. You can solve this problem by using LabWindows/CVI to generate an

DLL Path (.pth) Files Not Supported

The DLL import library contains the filename of the DLL. LabWindows/CVI uses the standard Windows DLL search algorithm to find the DLL. Thus, DLL path ( files do not work under Windows 95/NT.

16-Bit DLLs Not Supported

LabWindows/CVI for Windows 95/NT does not load 16-bit DLLs. If you want to do this, you must obtain a 32-to-16-bit thunking DLL and a 32-bit DLL import library.

Run State Change Callbacks in DLLs

You can include run state change callbacks in DLLs you build in LabWindows/CVI. When running a program in LabWindows/CVI, a run state change callback receives notification when the program starts, suspends, resumes, and stops. If you include a run state change
.pth)
LabWindows/CVI Programmer Reference Manual 3-2
©
National Instruments Corporation
callback in a DLL, you must take special care. Refer to the Notification of Changes in Run
State section in Chapter 2, Using Loadable Compiled Modules, of this manual, for a detailed
discussion of run state change callbacks.

DllMain

Each DLL can have a DllMain function, except that the Borland compiler uses
DllEntryPoint as the name. The operating system calls the DllMain function with various
messages. To generate the template for a command in the Edit menu of a Source w indow.
Chapter 3 Windows 95/NT Compiler/Linker Issues
DllMain function, use the Insert Constructs
Use caution when inserting code in the
PROCESS_ATTACH and PROCESS_DETACH cases. In
particular, avoid calling into other DLLs in these two cases. The order in which Windows 95/NT initializes DLLs at startup and unl oads them at process termination is not well-defined. Thus, the DLLs you want to call might not be in memory when your receives the
PROCESS_ATTACH or PROCESS_DETACH message.
It is always safe to call into the LabWindows/CVI Run-time Engine in a run state change callback, as long as you do so before calling
CloseCVIRTE.

Releasing Resources when a DLL Unloads

When a program terminates, the operating system disposes resources your DLL allocates. If your DLL remains loaded throughout program execution, it does not need to dispose resources explicitly when the system unloads it at program termination. However, if the program unloads your DLL during program execution, it is a good idea for your DLL to dispose of any resources it allocates. It can release resources in the response to the that it registers with the ANSI C when the DLL receives the
If your DLL calls into the LabWindo ws/CVI Run-time Engine DLL, it can allocate resources such as user interface panels. If a program unloads your DLL during execution, you might want to dispose these resources by calling functions such as LabWindo ws/CVI R un-tim e Engine. On the ot her hand, as e xplaine d in the pre viou s section, it is generally unsafe to call into other DLLs in response to the
PROCESS_DETACH message. The DLL can also release resources in a function
atexit function. The system calls the function you register
PROCESS_DETACH message.
DllMain
DllMain function in
DisposePanel in the
PROCESS_DETACH message.
To solve this dilemma, you can use the Utility Library. It is always safe to call the
CVIRTEHasBeenDetached returns FALSE until the main Run-time Engine DLL, cvirte.dll, receives the PROCESS_DETACH message. Consequently, if CVIRTEHasBeenDetached returns FALSE, your DLL can safely call functions in
CVIRTEHasBeenDetached function in the
CVIRTEHasBeenDetached function.
LabWindows/CVI Run-time Engine to release resources.
©
National Instruments Corporation 3-3 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues
Note cvirte.dll contains the User Interface, Utility, Formatting and I/O, RS-232,
ANSI C, TCP, and DDE Libraries.

Generating an Import Library

If you do not have a DLL import library or if the one you have contains references the DLL does not export, you can generate an import library in LabWindows/CVI. You must have an include file that contains the declarations of all the functions and global v ariables you want to access from the DLL. The calling conventions of the function declarations in the include file must match the calling convention of the functions in the DLL. For example, if the DLL exports functions using the include file must contain the window, and select the Generate DLL Import Library command in the Options menu.
__stdcall calling convention, the function declarations in the
__stdcall keyword. Load the include file into a Source

Default Unloading/Reloading Policy

Some fundamental differences exist in the way Windows 95/NT and Windows 3.1 handle a DLL that multiple processes use.
Windows 95/NT creates a separate data space for each process that uses the DLL. Windows 3 .1 creates only one data space for all processes that use the DLL.
Windows 95/NT notifies a DLL each time a process loads or unloads it. Windows 3.1 does not notify a DLL each time a process loads or unloads it. Windo ws 3.1 n otif ies the DLL on ly when the first process loads it and the last process unloads it.
LabWindows/CVI for Windows 95/NT unloads DLLs, by default, after each execution of a user program in the development environment. This behavior more accurately simulates what happens when you execute a standalone executable, and it is more suitable for Windo ws 95/NT DLLs that rely on load/unload notification on each ex ecution of a program. You can change the def ault beha vi or by turning of f the Unload DLLs After Each Run option in the Run Options dialog box of the Project window. National Instruments recommends, however, that you leave the default behavior in effect.

Compatibility with External Compilers

LabWindows/CVI for Windows 9 5/ NT can be compatible at the object code level with any of the four compatible external compilers (Microsoft Visual C/C++, Borland C/C++, Watcom C /C++, and Symantec C/C++). Because these compilers are not compatible with each other at the object code level, LabWindows/CVI can be compatible with only one external compiler at a time. This manual refers to the compiler with which your copy of LabWindows/CVI is currently compatible as the current compatible compiler.
LabWindows/CVI Programmer Reference Manual 3-4
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues

Choosing Your Compatible Compiler

When installing LabWindows/CVI, y ou m us t choos e yo ur co mpat ibl e co mpil er. If y ou w a nt to change your choice of compatible compiler later, you can run the installation program and change to another compatible compiler.
You can see which compatible compiler is active in LabWindows/CVI by selecting the Compiler Options command in the Options menu of the Project window.
Object Files, Library Files, and DLL Import Libraries
If you create an object f i le, l ibrary file, or DLL import li br ary in LabWindows/CVI, you can use the file only in the current compatible compiler or in a copy of LabWindows/CVI that you installed with the same comp atibility choice. For detailed information on using LabWindows/CVI-generated object and static library files in external compilers, refer to the Using LabWindows/CVI Libr aries in External Compilers section later in thi s chap ter.
If you load an object file, library file, or DLL import library file in LabWindows/CVI, you must have created the file in the current compatible compiler or in a copy of LabWindows/CVI that you installed with the same compatibility choice. If you have a DLL but you do not have a compatible DLL import library, LabWindows/CVI reports an error when you attempt to link your project.
To create a compatible import library, you must have an include file that contains the declarations of all the functions and global variables you want to access from the DLL. Load the include file into a Source window, and select the Generate DLL Import Library command in the Options menu.
Make sure the calling conventions of the function declarations in the include file match the calling convention of the functio ns in the DLL. Whereas DLLs usually export functions with
__stdcall calling convention, the __stdcall keyw ord is somet imes mi ssing from t he
the function declarations in the associated include files. If you generate an imp ort library from an include file that does not agree with the calling convention the DLL uses, you can successfully build a project that contains the import library, but LabWindows/CVI usually reports a general protection fault when you run the project.

Compatibility Issues in DLLs

In general, you can use a DLL without regard to the compiler you used to create it. Only the DLL import library must be created for the current compatible compiler. Some cases exist, however, in which you cannot call a DLL that you created using one compiler from an executable or DLL that you created using another compiler. If you want to create DLLs that you can use in different compilers, design the Application Programming Interface (API) for your DLL to avoid such problems. The following are areas in which the DLLs that external compilers create are not fully compatible.
©
National Instruments Corporation 3-5 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues
Structure Packing
The compilers differ in their default maximum alignment of elements within structures. If your DLL API uses structures, you can guarantee compatibility among the different
compilers by using the this pragma in the DLL include file, before the definitions of the structures. You can choose any alignment factor . After the structure definitions, reset the maximum alignment factor back to the default, as in the following example:
#pragma pack (4) /* set maximum alignment to 4 */
typedef struct { char a; int b; } MyStruct1;
typdef struct { char a; double b; } MyStruct2;
pack pragma to specify a specific maximum alignment factor. Place
#pragma pack () /* reset max alignment to default */
LabWindows/CVI predefines the __DEFALIGN macro to the default structure alignment of the current compatible compiler.
Bit Fields
Borland C/C++ uses the smallest number of bytes necessary to hold the bit f ields you specify in a structure. The other compilers always use 4-byte elements. You can force compatibility by adding a dummy bit field of the correct size to pad the set of contiguous bit fields so that they fit exactly into a 4-byte element. Example:
typedef struct { int a:1; int b:1; int c:1; int dummy:29; /* pad to 32 bits */ } MyStruct;
LabWindows/CVI Programmer Reference Manual 3-6
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
Returning Floats and Doubles
The compilers return float and double scalar values using different mechanisms. This is true of all calling conventions, including to change your DLL API so that it uses output parameters instead of return values for
float scalars.
and
__stdcall. The only solution for this problem is
double
Returning Structures
For functions you do not declare with the __stdcall calling convention, the compilers return structures using diffe rent mechanisms. For functions you declar e with compilers return structures in the same way, except for 8-byte structures. National Instruments recommends that your DLL API use structure output parameters instead of structure return values.
__stdcall, the
Enum Sizes
By default, Watcom uses the smallest integer size necessary to represent the largest enum value: 1 byte, 2 bytes, or 4 bytes. The other compilers always use 4 bytes. Force compatibility by using the
-ei (Force Enums to Type Int) option with the Watcom compiler.
Long Doubles
In Borland C/C++, long double values are 10 bytes. In the other compilers, the y are 8 bytes. In LabWin dows/CVI, they are al ways 8 bytes. Avoid using
long double in your DLL API.
Differences between LabWindows/CVI and the External Compilers
LabWindows/CVI does not work with all the non-ANSI extensions each external compiler provides. Also, in cases where ANSI does not specify the exact implementation, LabWindows/CVI does not always agree with the external compilers. Most of these differences are obscure and rarely encountered. The following are the most important differences you might encounter:
wchart_t is only one-byte in LabWindows/CVI.
64-bit integers do not exist in LabWindows/CVI.
long double values are 10 bytes in Borland C/C++ but 8 bytes in LabWindows/CVI.
You cannot use structured exception handling in La bWindows/CV I.
Y ou cannot use the W atcom C/C++ __ functions that return is not the default calling convention.
LabWindows/CVI does not define
__SC__. The external compilers each define one of these macros. If you port code
©
National Instruments Corporation 3-7 LabWindows/CVI Programmer Reference Manual
float or double scalar values or structures. In Watcom, __cdecl
cdecl calling convention in LabWindows/CVI for
_MSC_VER, __BORLANDC__, __WATCOMC__, and
Chapter 3 Windows 95/NT Compiler/Linker Issues
originally developed under one of these external compilers to LabWindows/CVI, you might have to manually define one of these macros.

External Compiler Versions Supported

The following versions of each external compiler work with LabWindows/CVI for Windows 95/NT:
Microsoft Visual C/C++, version 2.2 or higher
Borland C/C++, version 4.51 or higher
Watcom C/C++, version 10.5 or higher
Symantec C/C++, version 7.2 or higher

Required Preprocessor Definitions

When you use an external compiler to compile source code that includes any of the LabWindows/CVI include files, add the following to your preprocessor definitions:
_NI_mswin32_

Multithreading and the LabWindows/CVI Libraries

Although the LabWindows/CVI environment is not multithreaded, you can use LabWindows/CVI Libraries in the following multithreaded contexts:
When you call the LabWindows/CVI Libraries from a multithreaded executable you create in LabWindows/CVI or in an external compiler.
When you call the LabWindows/CVI Libraries from a DLL that a multithreaded executable loads. You can create the DLL in LabWindows/CVI or in an external compiler.
When you call the LabWindows/CVI Libraries from an object or static library file that you dynamically load in a multithreaded e x ecutable. You can create the object or library file in LabWindows/CVI or in an external compiler.
All the LabWindows/CVI libraries are multithreaded safe when used outside of the LabWindows/CVI development environment.
For detailed information on how to use the LabWindows/CVI User Interface Library in a multithreaded program, refer to Chapter 3, Programming with the User Interface Library , in the LabWindows/CVI User Interface Reference Manual.
LabWindows/CVI Programmer Reference Manual 3-8
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
Using LabWindows/CVI Libraries in External Compilers
Under Windows 95/NT, you can use the LabWindows/CVI libraries in any of the four compatible external compilers. You can create executables and DLLs that call the LabWindows/CVI libraries. LabWindows/CVI ships with the run-time DLLs that contain all the libraries. Executable files you create in LabWindows/CVI also use these DLLs. The
cvi\extlib directory contains DLL import libraries and a startup library, all compatible
with your external compiler. Nev er use the compiler.
You must always include the following two libraries in your external compiler project:
cvisupp.lib /* startup library */ cvirt.lib /* import library to DLL containing:*/
/* User Interface Library */ /* Formatting and I/O Library */ /* RS-232 Library */ /* DDE Library */ /* TCP Library */ /* Utility Library */
You can add the following static library file from cvi\extlib to your external compiler project:
analysis.lib /* Analysis or Advanced Analysis Library */
.lib files in the cvi\bin directory in an external
You can add the following DLL import library files from cvi\extlib to your external compiler project:
gpib.lib /* GPIB/GPIB 488.2 Library */ dataacq.lib /* Data Acquisition Library */ easyio.lib /* Easy I/O for DAQ Library */ visa.lib /* VISA Transition Library */ nivxi.lib /* VXI Library */ ivi.lib /* IVI Library */ cviauto.lib /* ActiveX Automation Library*/
If you use an instrument dri ver that makes references to b oth the GPIB and VXI librari es, you can include both
gpib.lib and nivxi.lib to resolve the references to symbols in those
libraries. If you do not have access to one of these files, you can replace it with one of following files:
gpibstub.obj /* stub GPIB functions */ vxistub.obj /* stub VXI functions */
©
National Instruments Corporation 3-9 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues
If you use an external compiler that requires a WinMain entry point, the following optional library allows you to define only
cviwmain.lib /* contains a WinMain() function which */
/* calls main() */
main in your program.
Include Files for the ANSI C Library and the LabWindows/CVI Libraries
The cvirt.lib import library contains symbols for all the LabWindows/CVI libraries, except the ANSI C standard library. When you create an executable or DLL in an external compiler, you use the compiler’s o wn ANSI C standard library . Because of this, you must use the external compiler’s include files for the ANSI C library when compiling source files. Although the include files for the other LabWindows/CVI libraries are in the directory, the LabWindows/CVI ANSI C include files are in the directory. Thus, you can specify
cvi\include as an include path in your ex ternal co mpiler
cvi\include\ansi
while at the same time using the external compiler’s version of the ANSI C include files.
cvi\include
Note
Use the external compiler’s ANSI C include files only when you compile a source file that you intend to link using the external compiler. If you intend to link the file in LabWindows/CVI, use the LabWindows/CVI ANSI C include files. This is true regardless of which compiler you use to compile the source file.
For more information, refer to the Setting Up Include Paths for LabWindows/CVI, ANSI C,
and SDK Libraries section later in this chapter.

Standard Input/Output Window

One effect of using the external compiler’s ANSI C standard library is that the printf and
scanf functions do not use the LabWindows/CVI Standard Input/Output window. If you
want to use
printf and scanf, you must create a console application, which is called a
character-mode executable in Watcom. You can continue to use the LabWindows/CVI Standard Input/Output Window by calling the
FmtOut and ScanIn functions in the Formatting and I/O library.

Resolving Callback References from .UIR Files

When you link your program in LabWindows/CVI, LabWindows/CVI keeps a table of the non-static functions that are in your project. When your program calls
LoadMenuBar, the LabWindows/CVI User Interface Library uses this table to find the
callback functions associated with the objects you load from the user interface resource
.uir) file. This is true whether y ou run your p rogram in t he LabW indo ws/CVI de vel opment
( environment or as a standalone execu table.
LoadPanel or
LabWindows/CVI Programmer Reference Manual 3-10
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
When you link your program in an external compiler, the external compiler does not make such a table available to the User Interface Library. To resolve callback ref erences, you must use LabWindows/CVI to generate an object file that contains the necessary table.
1. Create a LabWindows/CVI project that contains the
.uir files your program uses, if you
do not already have one.
2. Select the External Compiler Support command in the Build menu of the Project
window. A dialog box appears.
3. In the UIR Callbacks Object File control, enter the p athname of the object file yo u wan t
to generate. When you click on the Create button, LabWindows/CVI generates the object file with a table that contains the names of all the callback functions referenced in
.uir files in the project. When you modify and save any of these .uir files,
all the LabWindows/CVI regenerates the object file to reflect the changes.
4. Include this object file in the external compiler project you use to create the executable.
5. You must call
InitCVIRTE at the beginning of your main or WinMain function. Refer
to the Calling InitCVIRTE and CloseCVIRTE section later in this chapter.
Linking to Callback Functions Not Exported from a DLL
Normally, the User Interface Library searches for callback functions only in the table of functions in the executable. When you load a panel or menu bar from a DLL, you might want to link to non-static callback functions the DLL contains, but does not export. You can do this by calling
LoadPanelEx and LoadMenuBarEx, the User Interface Library searches the table of
callback functions the DLL contains before searching the table that the executable contains. Refer to Chapter 4, User Interface Librar y Function Reference, of the LabWindow s/CVI User Interface Reference Manual for detailed information on
LoadMenuBarEx.
LoadPanelEx and LoadMenuBarEx. When you pass the DLL module handle to
LoadPanelEx and
If you create your DLL in LabWindows/CVI, LabWindows/CVI includes the table of functions in the DLL automatically. If you create your DLL using an external compiler, you must generate an object file that contains the necessary table as follows.
1. Create a LabWindows/CVI project that contains the
.uir files your DLL loads, if you
do not already have one.
2. Select the External Compiler Support command in the Build menu of the Project
window. A dialog box appears.
3. In the UIR Callbacks Object File control, enter the p athname of the object file yo u wan t
to generate. When you click on the Create button, LabWindows/CVI generates the object file with a table that contains the names of all the callback functions referenced in
.uir files in the project. When you modify and save any of these .uir files,
all the LabWindows/CVI regenerates the object file to reflect the changes.
©
National Instruments Corporation 3-11 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues
4. Include this object file in the external compiler project you use to create the DLL.
5. You must call
InitCVIRTE and CloseCVIRTE in your DLLMain function. Refer to the
Calling InitCVIRTE and CloseCVIRTE section later in this chapter.
Resolving References from Modules Loaded at Run-Time
Note
This section does not apply unless you us e LoadExternalModule to load object or static library files.
Unlike DLLs, object and static library files can contain unresolved references. If you call
LoadExternalModule to load an object or static library file at run time, the Utility
Library must resolve those references using function and variable symbols from the LabWindows/CVI Run-time Engine, from the executable, or from previously loaded run-time modules. A table of these symbols must be available in the executable. When you link your program in LabW indows/CVI, LabW indows/C VI automatically includes a symbol t able. This is true whether you run your program in the LabW in dows/CVI dev e lo pmen t environmen t or as a standalone executable.
When you link your program in an external compiler, the external compiler does not make such a table available to the Utility Library. LabWindows/CVI provides ways to help you create the symbol table easily.
Resolving References to the LabWindows/CVI Run-Time Engine
LabWindows/CVI makes available two object files that contain symbol table information for the LabWindows/CVI libraries that are in Run-time Engine DLLs:
Include modules refer to any symbols in the User Interface, Formatting and I/O, RS-232, DDE, TCP, or Utility Library.
Include modules refer to any symbols in the ANSI C library . If you ha ve to use thi s object fil e and you use Borland C/C++ to create your executable, you must choose Static Linking for the Standard Libraries. In the Borland C/C++ IDE, you can do this in the New Target and Target Expert dialog boxes.
cvi\extlib\refsym.obj in your external compiler project if your run-time
cvi\extlib\arefsym.obj in your external compil er project if your run- time
Resolving References to Symbols Not in Run-Time Engine
If your run-time modules refer to any other symbols from your executable, you must use LabWindows/CVI to generate an object f ile that contains a table of those symbo ls. Create an include file that contains complete declarations of all the symbols your run-time mo dules reference from the executable. The include f ile can contain nested can contain executable symbols that your run-time modules do not refer to. If your run-time
LabWindows/CVI Programmer Reference Manual 3-12
#include statements and
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
module references any of the commonly used Windows SDK functions, you can use the
cvi\sdk\include\basicsdk.h file.
Execute the External Compiler Support command in the Build menu of the Project window . A dialog box appears. Enable the Using Load External Module option. Enable the Other Symbols checkbox if it is not already enabled. Enter the pathname of the include file in the Header File control. Enter the pathname of the object file to generate in the Object File control. Click on the Create button to the right of the Object File control.
Include the object file in the external compiler project you use to c reate your executable. Also, you must call
InitCVIRTE at the beginning of your main or WinMain function. Refer to the
Calling InitCVIRTE and CloseCVIRTE section later in this chapter.
Resolving Run-Time Module References to Symbols Not Exported from a DLL
When you load an object or static library file from a DLL, you might want to resolve references from that module using global symbols the DLL contains, but does not export. You can do this by calling
LoadExternalModuleEx, the Utility Library searches the symbol table the DLL contains
before searching the table that the executab le contains. Refer to Chapter 8, Utility Library, of the LabWindows/CVI Standard Libraries Reference Manual for detailed information on
LoadExternalModuleEx.
LoadExternalModuleEx. When you pa ss th e DLL modu le h andle to
If you create your DLL in LabWin dows/CVI, LabW indows/C VI includes the ta ble of symbols in the DLL automatically. If you create your DLL using an external compiler, the external compiler does not make such a table available to the Utility Library. Thus, when you use an external compiler, you must include in your DLL one or more object files that contain the necessary symbol tables. You can do this using the technique that the previous section,
Resolving References to Symbols Not in Run-Time Engine, describes. You must call
InitCVIRTE and CloseCVIRTE in your DLLMain functio n. Refer to the Calling InitCVIRTE
and CloseCVIRTE section later in this chapter.
Run State Change Callbacks Are Not Available in External Compilers
When you use a compiled module in LabWindows/CVI, you can arrange for LabWindows/CVI to notify the module of a ch ange in the e xecution status such as start, stop, suspend, or resume. You do this through a callback function that is always named
__RunStateChangeCallback. The Notification of Changes in Run State section, in
Chapter 2, Using Loadable Compiled Modules, of this manual, describes this in detail. The run state change callback capability in LabWindows/CVI is necessary because the
LabWindows/CVI development environment executes your program as part of the LabWindows/CVI process. When your program terminates, the operating system does not release resources as it does when a process terminates. LabWindo ws/CVI attempts to release
©
National Instruments Corporation 3-13 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues
resources your prog ram allocated, but yo ur compiled m odule mi ght ha ve t o do more. Also , if the program suspends for de bugging purposes , you r compi le d module mi gh t have to disable interrup ts.
When you run an executable created in an e xternal compiler, it always ex ecutes as a separate process, even when you debug it. Thus, the run state change callback facility is not necessary and does not work. External compilers report link errors when you define
__RunStateChangeCallback in more than one object file. If you include a run state
change callback in a compiled module that you intend to use both in LabWindows/CVI and an external compiler , it is a good idea to put the callback function in a separate source file and create a
.lib file instead of a .obj file.

Calling InitCVIRTE and CloseCVIRTE

If you link an executable or DLL in an external compiler, you must call the InitCVIRTE function at the beginning of your
main, WinMain, or DLLMain function.
For an executable using
main as the entry point, your code must include the following
segment:
#include <cvirte.h> int main (argc, char *argv[]) {
if (InitCVIRTE(0, argv, 0) == 0)
return (-1);/* out of memory */
/* your other code */
}
For an executable using WinMain as the entry point, your code must include the following segment:
#include <cvirte.h> int __stdcall WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
if (InitCVIRTE(hInstance, 0, 0) == 0)
return (-1);/* out of memory */
/* your other code */
}
LabWindows/CVI Programmer Reference Manual 3-14
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
For a DLL, you also have to call CloseCVIRTE in DLLMain. The code must include the following segment:
#include <cvirte.h> int __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID pvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { if (InitCVIRTE (hinstDLL, 0, 0) == 0) return 0; /* out of memory */ /* your other ATTACH code */ }
else if (fdwReason == DLL_PROCESS_DETACH) { /* your other DETACH code */ CloseCVIRTE ();
} return 1; }
Note
It is harmless, but unnecessary, to call these functions when you link your executable in LabWindows/CVI for Windows 95/NT.

Watcom Stack Based Calling Convention

When you use the LabWindows/CVI libraries in the Watcom compiler, you must set the default calling conv ention to the 8 0486 Stack Based calling convention. In the command line compiler, this is the
-4s option. In the W atcom IDE, you can set the default calling convention
by using the Options»C Compiler Switches command. The option is in the T arget Processor section of the Memory Model and P rocessor Switches section of the dialog box. If you do not set this option, the Watcom linker reports undefined references to the LabWindows/CVI run-time libraries.
Using Object and Library Files in External Compilers
When you use an external compiler to link a project that contains ob ject or static library f iles created in LabWindows/CVI, keep several points in mind.

Default Library Directives

Most compilers insert default library directives in the object and library files they generate. A default library directive tells the linker to automatically include a named library in the link. Normally, the directive refers to the name of C library files. If no files in the link contain a
©
National Instruments Corporation 3-15 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues
default library directive, and the linker does not explicitly include a C library in the link, the linker reports unresolved function references in the object modules.
Object and static library files that LabWindows/CVI creates do not contain a default library directive. This has different implications for each compiler.
Microsoft Visual C/C++
If you include in your project at least one object file that contains a default library directive, the Visual C linker uses that library to resolve references in all object and library files, even the files you create in LabWindo ws/CVI. Object files you create in Visual C usually contain default library directives.
If you do not include in your project any object files or libraries you create in Visual C, you can add the following Visual C libraries to the project to avoid link errors:
libc.lib oldnames.lib
In the V isual C development environment, add these library names using the Input category in the Link tab of the Project Settings dialog box.
Borland C/C++
No problems exist with the absence of default library directives when you use the Borland compiler.
Watcom C/C++
Like Visual C, at least one object file must contain a default library directive to cause the C library to be linked in. In addition, Watcom also requires a default library directive for floating-point support.
If you do not include in your project any object files with the required directives, add the following libraries, in the order shown, to the Libraries setting in the Windows Linking Switches dialog box:
clib3s math387 noemu387
Symantec C/C++
Each object file must have the default library directive for the C library. You must explicitly add the Symantec C library to your project. The library filename is
lib subdirectory under the Symantec installation directory.
LabWindows/CVI Programmer Reference Manual 3-16
snn.lib and it is in the
©
National Instruments Corporation

Borland Static versus Dynamic C Libraries

When you link a Borland C/C++ project that contains object or static library files you create in LabWindo ws/CVI, it is a good idea to configure the Borland project to use the static version of the Borland C libraries.
If you choose to use the dynamic C libraries, you must compile the LabWindows/CVI object modules with the before including any of the Borland C header files.
_RTLDLL macro. You must define the _RTLDLL macro in your source code

Borland Incremental Linker

Y ou cannot use your LabWindo ws/CVI object or static library files in the Borland C compiler if you choose to use the incremental linker. Turn off the Use Incremental Linker option.

Borland C++ Builder

You cannot use your LabWindows/CVI object or static library files in the Borland C++ Bui lder.

Watcom Pull-in References

The W atcom linker does not automatically link the startup code into your application or DLL. Instead, it requires the module that contains special symbol that the appropriate startup code module resolves. The Watcom compiler automatically generates a reference to the special symbol into any module that contains
WinMain, or DllMain. This symbol is __DLLstart_, _wstart2_, or _cstart_,
depending on whether the project is for a DLL, W indo ws application, or console app lication, respectively. Object modules compiled in LabWindows/CVI do not contain such r eferences. LabWindows/CVI cannot generate the correct reference because it makes no distinction between console and non-console applications.
main, WinMain, or DllMain to reference a
Chapter 3 Windows 95/NT Compiler/Linker Issues
main,
You must include the symbol reference in your object file explicitly. For example, if your module contains the the following to the source code for the module:
extern int _cstart_; void *dummy = &_cstart_;
©
National Instruments Corporation 3-17 LabWindows/CVI Programmer Reference Manual
main function, you can generate the corr ect symbol reference b y addin g
Chapter 3 Windows 95/NT Compiler/Linker Issues
Creating Object and Library Files in External Compilers for Use in LabWindows/CVI
When you use a compatible external compiler to create an object or library file for use in LabWindows/CVI, you must use the include files in the
cvi\sdk\include directories. Ensure that these directories have priority over the
default paths for the compiler’s C library and SDK library include files. You must choose the compiler options carefully. LabWindows/CVI tries to work with the
default options for each compiler as much as possible. In some cases, however, you have to choose options that override the defaults. In other cases you must accept the defaults.

Microsoft Visual C/C++

LabWindows/CVI is compatible with all the defaults. You must not use the following options to override the default settings:
cvi\include and
/J
/Zp
/Ge
/Gh
/Gs

Borland C/C++

LabWindows/CVI is compatible with all the defaults. You must not use the following options to override the default settings:
-a
-K
-u-
-N
-p
-pr
-fp
(Unsigned Characters) (Struct Member Alignment) (Stack Probes) (Profiling) (Stack Probes)
(Data Alignment) (Unsigned Characters) (Turn Off Generation of Underscores) (Test Stack Overflow) (Pascal Calling Convention) (Register Calling Convention) (Correct Pentium FDIV Flaw)
LabWindows/CVI Programmer Reference Manual 3-18
©
National Instruments Corporation

Watcom C/C++

You must use the following options to override the default settings:
Chapter 3 Windows 95/NT Compiler/Linker Issues
-ei
-bt=nt
-mf
-4s
-s
-j
-fpi87
If your external object calls also add the following compiler option:
-d__NO_MATH_OPS
You must not use the following option to override the default settings:
-Zp

Symantec C/C++

You must use the following options to override the default settings:
-mn
(Force Enums to Type Int) (Target Platform is Windows 95/NT) (Flat Memory Model) (80486 Stack-Based Calling) (Disable Stack Depth Checking) (Change Char Default to Signed) (Generate In-Line 80x87 Code)
LoadExternalModule or LoadExternalModuleEx, you mu st
(Structure Alignment)
(Windows 95/NT Memory M odel)
-f
(Generate In-Line 80x87 Code)
You must not use the following options to override the default settings:
-a
-P
-s
Note
(Struct Alignment) (Use Pascal Calling Convention) (Check Stack Overflow)
Certain specialized options can generate symbol references that cause link errors in LabWindows/CVI. If you encounter a link error on a symbol in a module you compiled in an external compiler and you do not recognize the symbol, try changing your external compiler options.
©
National Instruments Corporation 3-19 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues

Creating Executables in LabWindows/CVI

Y ou can create true 32-bit W indows e xecutables in LabW indows/CVI fo r Windo ws 95/NT. In LabWindo ws/CVI for Windo ws 3.1, you run standalone programs using a special e xecut able file that contains the LabWindows/CVI run-time libraries. at a time, Windows 3.1 loads extra copies of this special executable into memory. Under Windows 95/NT, the LabWindows/CVI run-time libraries come in DLL form. Standalone executables you create in LabW ind ows/CVI and e xecutables you create in external compilers use the same DLLs. If you run more t han one pro gram at a time, Windows 95/NT lo ads only one copy of the DLL.
To create a standalone executable, you must first select Standalone Executable fro m the submenu attached to the Target command in the Build menu of the Project window. When you select Standalone Executable, the Create Standalone Executable command appears below the Target command in the Build menu. The Create Standalone Executable command under Win dows 95/NT is the same as under Windows 3.1, except that you also can specify version information to include in the executable in the form of a standard Windows version resource.
If you run more than one program

Creating DLLs in LabWindows/CVI

In LabWindows/CVI for Windows 95/NT, you can create 32-bit DLLs. Along with each DLL, LabWindows/CVI creates a DLL import library for your com patible compiler . You can choose to create DLL import libraries compatible with all four external compilers.
You must have a separate project for each DLL you want to create. Select Dynamic Link Library from the submenu attached to the Target command in the Build menu of the Project window. When you select Dynamic Link Library, the Create Dynamic Link Library command appears below the Target command in the Build menu. Refer to Chapter 3, Project
Window , in the LabWindows/CVI User Manual, for detailed information on the Create Dynamic Link Library command.
You can debug the DLLs you create in LabWindows/CVI. Refer to
(Windows 95/NT Only)
User Manual, for more information.
section in Chapter 3, Project Window, of the LabWindows/CVI

Customizing an Import Library

If you have to perform special processing in your DLL import library, you can customize it. Instead of generating a do this, however, you can export only functions from the DLL, not variables.
LabWindows/CVI Programmer Reference Manual 3-20
.lib file, you can generate a .c f ile that contains source code. If you
DLL Debugging
the
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
To customize an import library, you must have an include file that contains the declarations of all the functions you want to export from the DLL. Load the include file into a Source window, and execute the Generate DLL Import Source command in the Options menu.
After you have generated the import source, you can modify it, including making calls to functions in other source files. Create a new project that contains the import source file and any other files it refers to. Select Static Library from the submenu attached to the Target command in the Build menu of the Project window. Execute the Create Static Library command.
Note This import source code does not operate in the same way as a normal DLL import
library. When you link a normal DLL import lib rary into an executable, the operating system attempts to load the DLL as soon as the program starts. The import source code LabWindows/CVI generates does not load th e DLL un til you call one of the functions it exports.

Preparing Source Code for Use in a DLL

When you create a DLL, you must address the following issues that can affect your source code and include file:
The calling convention you use to declare the functions you want to export
How you specify which DLL functions and variables you want to export
Marking imported symbols in the DLL include file you distribute This section discusses how you can address these issues when you create your DLL in
LabWindows/CVI. If you create your DLL in an external compiler, the approach is very similar. The external compilers, however, do not agree in all aspects. This chapter also discusses these differences.
Some of the information in this section is very technical an d complex. Recommend ations on the best approaches to these issues are at the end of the section. These recommendations are intended to make creating the DLL as simple as possible, and to make it easy to use the same source code in LabWindows/CVI and the external compilers.
Calling Convention for Exported Functions
If you intend for only C or C++ programs to use your DLL, you can use the __cdecl or Watcom stack-based calling convention to declare the functions you want to export. If, however, you want your DLL to be callable from environments such as Microsoft Visual Basic, you must declare the functions you want to export with the convention.
You must do this by explicitly defining the functions with the _ true whether or not you choose to make _
©
National Instruments Corporation 3-21 LabWindows/CVI Programmer Reference Manual
_stdcall the default calling convention for your
__stdcall calling
_stdcall keyword. This is
Chapter 3 Windows 95/NT Compiler/Linker Issues
project. You must use the __stdcall keyword in the declarations in the include file you distribute with the DLL.
Other platforms, such as UNIX or Windows 3.1 do not recognize the
__stdcall keyword.
If you work with source code that you might us e on other platfo rms, you must use a macro in place of
__stdcall. The cvidef.h include file defines the DLLSTDCALL macro for this
purpose. The following are examples of using the
int DLLSTDCALL MyIntFunc (void); char * DLLSTDCALL MyStringFunc (void);
Note
You cannot use the __stdcall calling convention on functions with a variabl e
DLLSTDCALL macro.
number of arguments. Consequently, you cannot use such functions in Microsoft Visual Basic.
Exporting DLL Functions and Variables
When a program uses a DLL, it can access only the functions or variables that the DLL exports. The DLL can expor t only globally declared functions and v ariables. The DLL cannot export functions and variables you declare as
static.
If you create your DLL in LabW ind ows /CVI, you can i ndicate which f unctions and va riables to export in two ways: the include file method and the qualifier method.
Include File Method
You can use include files to identify symbols to export. The include files must contain the declarations of the symbols you want to export. The include files can contain nested
#include statements, but the DLL does not export the declarations in the nested include
files. In the Create Dynamic Link Library dialog box, you select from a list of all the include files in the project.
The include file method does not work with other compilers. However, it is similar to the
.def method that the other compilers use.
Export Qualifier Method
You can mark each function and variable you want to export with an export qualifier. Currently , not all compilers recognize the same e xpor t qualifier names. The most commonly used qualifier is LabWindows/CVI recognizes both. The
LabWindows/CVI Programmer Reference Manual 3-22
__declspec(dllexport). Some also recognize __export.
cvidef.h include file defines the DLLEXPORT
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
macro to resolve diff erences among compilers a nd platform s. The f ollo wing are e xamples of using the
int DLLEXPORT DLLSTDCALL MyFunc (int parm) {} int DLLEXPORT myVar = 0;
DLLEXPORT macro:
If the type of your v ari able or f unction requir es an ast erisk ( *) in the syntax, put the qualifier after the asterisk, as in the following example:
char * DLLEXPORT myVar = NULL;
Note Borland C/C++ version 4.5x, requires that you place the qualifier before the
asterisk. In Borland C/C++ 5.0, you can place the qualifier on either side of the asterisk.
When LabWindows/CVI creates a DLL, it exports all symbols for which export qualifiers appear in either the definition or the declaration. If you use an export qualifier on the definition and an import qualifier on the declaration, Lab Windows / CVI e x ports the symbol. The external compilers differ widely in their behavior on this point. Some require that the declaration and definition agree.
Note If you include in your DLL project an object or library file that defines exported
symbols, LabWindows/CVI cannot correctly create import libraries for each of the external compilers. This problem does not arise if you use only source code files in your DLL project.
Marking Imported Symbols in Include File Distributed with DLL
If your DLL might be used in a C or C++ environment, you must distribute an include file with your DLL. The include f ile must declare all the symb ols the DLL ex ports. If an y of these symbols are variables, you must mark them with an import qualifier. Variable declarations require import qualifiers so that the compiler can generate the correct code for accessing the variables.
You can use impo rt qualif iers on function d eclarations, but they are not necessary. When you use an import qualifier on a function declaration, external compilers can generate slightly more efficient code for calling the function.
Using import qualifiers in the include file you distribute with your DLL can cause problems if you use the same include file in the DLL source code:
If you mark variable declarations in the include file with import qualifiers and you use
the include file in a source file other than the one in which you define the variable,
LabWindows/CVI and the external compilers treat the variable as if it were imported
from another DLL and generate incorrect code as a result.
If you use export qualifiers in the definition of symbols and the include file contains
import qualifiers on the same symbols, some external compilers report an error.
©
National Instruments Corporation 3-23 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues
You can solve these problems in several different ways:
You can avoid exporting variables from DLLs, and thereby eliminate the need to use import qualifiers. For each variable you want to export, you can create functions to get and set its value or a function to return a pointer to the variable. You do not have to use import qualifiers for functions. This is the simplest approach and works in LabWindows/CVI. However, it does not work if you use an export qualifier in a function definition and you create the DLL with an external compiler that requires the declaration to use the same qualifier.
You can create a separate include file for distribution with the DLL.
You can use a special macro that resolves to either an import or export qualifier depending on a conditional compilation flag. In LabWindows/CVI you can set the flag in your DLL project by using the Compiler Defines command in the Options menu of the Project window.
Recommendations
To make creating a DLL as simple as possible, adhere to the following recommendations:
•Use the to export. Do not export functions with a variable number of arguments.
Identify the symbols you w ant to export usi ng the include fi le method. Do not use e xport qualifiers. If you use an external compiler, use the
Do not export variables from the DLL. For each variable you want to export, create functions to get and set its value or a function to return a pointer to the variable. Do not use import qualifiers in the include file.
DLLSTDCALL macro in the declaration and definition of all functions you want
.def file method.
If you follow these recommendations, you reap the following benefits:
Y ou can distribute with your DLL the same include file that you include in the source files you use to make the DLL. This is especially useful when you create DLLs from instrument drivers.
You can use the same source code to create the DLL in LabW indo ws/CVI and an y of the four compatible external compilers.
You can use your DLL in Microsoft Visual Basic or other non-C environments.
Automatic Inclusion of Type Library Resource for Visual Basic
The Create Dynamic Link Library command gives you the option to automatically create a Type Library resource and include it in the DLL. When you use this option, Visual Basic users can call the DLL without having to use a header file that contains for the DLL functions. The command requires that you have a function panel file for your DLL.
LabWindows/CVI Programmer Reference Manual 3-24
Declare statements
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
If your function panel file contains help text, you can generate a Windows help file from it using the Generate Windows Help command in the Options menu of the Function Tree Editor window . The Create Dynamic Link Library command provides an option to include links into the Window help file in the Type Library. These links allow Visual Basic users to access the help information from the Type Library Browser.
Visual Basic has a more restricted set of types than C. Also, the Create Dynamic Link Library command imposes certain requirements on the declaration of the DLL API. Use the following guidelines to ensure that Visual Basic can use your DLL:
Always use typedefs for structure parameters and union parameters.
Do not use enum parameters.
Do not use structures that require forward references or that contain pointers.
Do not use pointer types except for reference parameters.

Creating Static Libraries in LabWindows/CVI

You can create static library (.lib) files in LabWindows/CVI for Windows 95/NT. Static libraries are libraries in the traditional sense—a collection of object files —as opposed to a dynamic link library or an import library. You can use just one project to create static library files that work with all four compatible external compilers, but only if you include no object or library files in the project.
You must have a separate project for each static library you want to create. Select Static Library from the submenu attached to the Target command in the Build menu of the Project window. When you select the Static Library option, the Create Static Library command appears below the Target command in the Build menu. Refer to Chapter 4, Source,
Interactive Execution and Standard Input/Output Windows, of the LabWindows/CVI User Manual for detailed information on the Create Static Library command.
Note
If you include a .lib file in a static library project, LabWindows/CVI includes all object modules from the
.lib in the static library it creates. When you create an
executable or DLL, LabWindows/CVI uses only the necessary modules from the
.lib file.
Note
Do not set the default calling convention to __stdcall if you want to create a static library for all four compatible external compilers.
©
National Instruments Corporation 3-25 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues

Creating Object Files in LabWindows/CVI

You can create an object file in LabWindows/CVI in one of two ways:
Include a source ( source file by double-clicking in the space next to the filename in the Project window under the column marked “O”. Compile the file.
Open a source ( of the Source window.
In LabWindo ws/CVI for W indo ws 95/NT, you can choose to create an object file for only the currently selected compiler or to create object files for all four compatible external compilers.
.c) file in your project. Enable the Compile into Object option for the
.c) file and select the Create Object File command in the Options menu
Note
Do not set the default calling convention to __stdcall if you want to create a static object for all four compatible external compilers.

Calling Windows SDK Functions in LabWindows/CVI

You can call Windows SDK Functions in LabWindows/CVI for Windows 95/NT. If you install the LabWindows/CVI full development system from CD-ROM, you can call all the Windows SDK functions. Otherwise, you can call only a subset of the Windows SDK functions.
To view help for the SDK functions, select the Windows SDK command in the Help menu of any LabWindows/CVI window.

Windows SDK Include Files

You must include the SDK include files before the LabWindows/CVI include files. In this way, you avoid problems that arise from function name and typedef conflicts between the Windows SDK and the LabWindows/CVI libraries. The LabWindows/CVI include files contain special macros and conditional compilation to adjust for declarations in the SDK include files. Thus, LabWindows/CVI must process the SDK include files first, followed by the LabWindows/CVI include files.
When you compile in LabWindows/CVI or when you use an external compiler to compile your source files for linking in LabWindows/CVI, use the LabWindows/CVI SDK include files. The LabW indows/CVI SDK include files are in the LabWindows/CVI compiler automatically searches the do not have to add it to your include paths.
cvi\sdk\include directory. The
cvi\sdk\include directory. You
When you use an external compiler to compile and link your source files, you must use the SDK include files that come with the external compiler. If you use an external compiler to compile your source files for linking in LabWindows/CVI, use the LabWindows/CVI SDK
LabWindows/CVI Programmer Reference Manual 3-26
©
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
include files. For more information, refer to the Setting Up Include Paths for
LabWindows/CVI, ANSI C, and SDK Libraries section later in this chapter.
The number of SDK include files is very large. Normally, you have to include only
windows.h because it includes many, b ut not all, of the other include files. The inclusion of windows.h along with its subsidiary include files significantly increases compilation time
and memory usage. compiling by elim in ating t he less commonly us ed por tions of include files. By default, LabWindows/CVI adds
WIN32_LEAN_AND_MEAN is a macro from Microsoft that speeds
windows.h and its subsidiary
/DWIN32_LEAN_AND_MEAN as a
compile-time definition when you create a new project. Y ou can alter this setting by using the Compiler Defines command in the Options menu of the Project window.
Using Windows SDK Functions for User Interface Capabilities
The LabWindows/CVI User Interface Library uses the Windows SDK. It is not designed to be used in programs that attempt to build other user interface objects at the SDK level. While no specific restrictions exist on using SDK functions in LabWindows/CVI, National Instruments recommends that you base your user interface either entirely on the LabWindows/CVI User Interface Library or entirely on another user interface development system.
Using Windows SDK Functions to Create Multiple Threads
Although you can use the Windows SDK Functions to create multiple threads in a LabWindows/CVI program, the LabWindows/C VI development environment cannot hand le multiple threads. For instance, if your main program terminates without destroying the threads, they do not terminate. Also, the LabWindows/CVI libraries are not multithread safe when you run a program in the LabWindows/CVI development environment.
For information on using the LabWindows/CVI libraries in a multithreaded executable, refer to the Multithreading and the LabWindows/CVI Libraries section earlier in this chapter.

Automatic Loading of SDK Import Libraries

All the SDK functions are in DLLs. LabWindows/CVI and the four external compilers each come with a number of DLL import libraries for the SDK functions. Most of the commonly used SDK functions are in the following three import libraries:
kernel32.lib gdi32.lib user32.lib
LabWindows/CVI for W indows 95/NT automatically loads these three libraries when it starts up and searches them to resolv e references at link time. Th us, you do not ha ve to include these libraries in your project.
©
National Instruments Corporation 3-27 LabWindows/CVI Programmer Reference Manual
Chapter 3 Windows 95/NT Compiler/Linker Issues
If the LabW indows/C VI linker r eports SDK function s as unresolv ed references, y ou must add import libraries to your project. Refer to the of SDK import libraries to SDK functions. The import libraries are in the directory.
cvi\sdk\sdkfuncs.txt file for associations
cvi\sdk\lib
Setting Up Include Paths for LabWindows/CVI, ANSI C, and SDK Libraries
The rules for using SDK include files are not the same as the rules for using ANSI C standard library include files, which in turn are different than the rules for using the LabWindows/CVI library include files. Refer to the Include Files for the ANSI C Library and the
LabWindows/CVI Libraries and Windows SDK Include Files sections earlier in this chapter.
You must set up your include paths differently depending on the environment in which you compile and link. A discussion of each case follows.
Compiling in LabWindows/CVI for Linking in LabWindows/CVI
Use the LabWindows/CVI SDK and ANSI C include files. You do not have to set up any special include paths; LabWindows/CVI finds the correct include files automatically.
Compiling in LabWindows/CVI for Linking in an External Compiler
Use the LabWindows/CVI SDK include files and the ANSI C include files from the external compiler. Using the Include Paths command in the Options menu of the Pr oject window , ad d the following as explicit include paths at the beginning of the project-specific list:
cvi\include cvi\sdk\include directory containing the external compiler's ANSI C include paths
Compiling in an External Compiler for Linking in an External Compiler
Use the SDK and ANSI C include files from the external compiler. This happens automatically. Specify the following directories as include paths in the external compiler for the LabWindows/CVI library include files.
cvi\include
©
LabWindows/CVI Programmer Reference Manual 3-28
National Instruments Corporation
Chapter 3 Windows 95/NT Compiler/Linker Issues
Compiling in an External Compiler for Linking in LabWindows/CVI
Use the LabWindows/CVI SDK and ANSI C include files. Specify the following directories as include paths in the external compiler.
cvi\include cvi\include\ansi cvi\sdk\include
Handling Hardware Interrupts under Windows 95/NT
Under Windows 3.1, you can handle hardware interrupts in a DLL. Under Windows 95, you must handle hardware interrupts in a VxD. Under Windows NT, you must handle hardware interrupts in a kernel-mode driver. You cannot create VxDs and kernel-mode drivers in LabWindows/CVI. Instead, you must create them in Microsoft Visual C/C++, and you also must have the Microsoft Device Driver Developer Kit (DDK).
Under Windows 3.1, it is extremely difficult to call source code into LabWindows/CVI at interrupt time. Making such a call is easier under Windows 9 5/NT. Under Windows 95/NT, you can arrange for the VxD or kernel-mode driver to call a function in your LabWindows/CVI source code after the interrupt service routine exits. Y ou do this by creating a separate thread for your interrupt callback function. The callback function executes a loop that blocks its thread until the interrupt service routine signals it. Each time the interrupt service routine executes, it unblocks the callback thread. The callback thread then performs its processing and blocks again.
LabWindows/CVI includ es source code template files for a VxD and a kernel mode driv er. It also includes a sample main program to show you ho w to read and write registers on a boar d. There is one se t of files for Windows 95 and anothe r for Windows NT.
The files are in directory contains some basic information.
©
National Instruments Corporation 3-29 LabWindows/CVI Programmer Reference Manual
cvi\vxd\win95 and cvi\vxd\winnt. The file template.doc in each
Windows 3.1 Compiler/Linker Issues
This chapter describes the different kinds of compiled modules available under LabWindows/CVI for Windows 3.1 and includes programming guidelines for modules you generate with external compilers.

Using Modules Compiled by LabWindows/CVI

Y o u can generate a compiled .obj or .o module fr om a source f ile within LabW in dows/ CVI using the Create Object File command in the Options menu of a Source window. You can then use the compiled module in any of the methods described in the About Lo ada bl e
Compiled Modules section in Chapter 2, Using Loadable Compil ed Modules, of this manual.
Using 32-Bit Watcom Compiled Modules under Windows 3.1
4
You must adhere to the following rules for a 32-bit Watcom compiled module (.obj or
.lib file):
You can call LabWindows/CVI library functions.
If you make a call to the ANSI C Standard Library, you must include the LabWindows/CVI header files instead of the Watcom header files.
You cannot call Watcom C library functions outside the scope of the ANSI C Standard Library.
You can call
lowlvlio.h from LabWindows/CVI.
You cannot call functions in the Windows Software Development Kit (SDK), install interrupts, perform DMA, or access hardware directly. These tasks must be done with a Dynamic Link Library (DLL). The ex ception to this is that you can use the functions.
You cannot define a function as from source code in LabW indo ws/CVI. Als o, you cannot u se any n on-ANSI-C-stand ard
©
National Instruments Corporation 4-1 LabWindows/CVI Programmer Reference Manual
open, close, read, write, lseek, or eof, but you must include
inp and outp
PASCAL, pascal, or _pascal if you intend to call it
Chapter 4 Windows 3.1 Compiler/Linker Issues
keywords su ch as far, near, or huge in the declaration of functions to be called from LabWindows/CVI source code.
If your Watcom-compiled module performs floating point operations, you must use Watcom Version 9.5 or later.
Use the following options when you compile with Watcom IDE: – Set the Project Target Environment to 32-bit Windows 3.x, and set the Image Type
to Library [.lib]. – Turn on the Disable Stack Depth Checkin g [-s] option. – Turn on the Change Char Default to Signed [-j] option. –Add Turn on the Generate as Needed [-of] option for Stack Frames. – Turn on the No Debugging Information option. – Turn on the In-line with Coprocessor [fpi87] option for Floating Point Model. – Turn on the Compiler default option for the Memory Model. – Turn on the 80486 Stack-Based Calling [-4s] option for the Target Processor.
Use the following compiler flags when using – – You can use optimization flags in addition to the f, and you can use other flags, such
-zw -d_NI_mswin16_ to the Other Options.
-zw -s -4s -j -fpi87 -d0 -of -d_NI_mswin16_
-wn, which do not affect the generation of object code.
as
wcc386 or wcc386p:
Using 32-Bit Borland or Symantec Compiled Modules under Windows 3.1
In this section, CVI refers to both LabWindows/CVI and Watcom modules, while Borland applies to both Borland and Symantec modules.
The following restrictions apply to Borland object modules:
Borland packs bit fields in structu res differently than CVI, so you cannot share structures with bit fields betwe en Borland and CVI.
Borland returns structures, floats, and doubles dif ferently than CVI. Therefore, functions that return these types cannot be called from CVI if they are defined in Borland, or vice versa. The exceptions are the ANSI C library functions that return doubles, which you can call from within Borland compiled modul e s.
Note
LabWindows/CVI Programmer Reference Manual 4-2
This rule applies only to return values. You can use structs, floats and doubles as output parameters without limitation.
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
ANSI C library functions div and ldiv return structures, and hence you cannot call them from Borland compiled modules.
The type
long double is the same as double in CVI, while in Borland it is 10 bytes
long, so you cannot share objects of this type between Borland and CVI modules. This affects the
scanf, sscanf, fscanf, and others.
"%Le", "%Lf", "%Lg" format specifiers of printf, sprintf, fprintf,
Because you cannot share structures with bit f ields between Borland and CVI, you cann ot use the macros in
wchar_t is defined as a char in CVI, whereas it is defined as a short in Bo rland,
so ANSI C library functions that return
stdio.h (getc, putc, fgetc, fputc) in Borland objects.
wchar_t or take wchar_t parameters do
not work.
Use the following options when you compile with Bo rland C 4.x:
Set the target to be a Win32 application.
•Define
Set the include directories to point to
_NI_mswin16_.
cvi\include before other include directories.
Turn off the Allocate Enums as Ints option.
Turn off the Fast Floating Point option.
Use the C calling convention.
If you use a file with a file has a
extern "C" for any functions or variables you want to access from a C file.
.cpp extension, Borland C++ 4.x compiles it as a C++ source file; you must use
.c extension, Borland C++ 4.x compiles it as a C source file. If your
Use the following options when you compile with Sy mantec C++ 6.0:
Set the target to be a Win32s executable.
Define
_NI_mswin16_.
Set the include directories to point to cvi\include before any other include directories.
Set Structure Alignment to 1 byte.
Turn off the Use Pascal Calling Convention option.

16-Bit Windows DLLs

You can call functions in a 16-bit DLL from source code or from a 32-bit compiled modu le. You can compile your 16-bit DLL in any language using any compiler that generates DLLs. If you want to program with DMA or interrupts, or access the W i ndo ws API, you must use a Windows DLL.
©
National Instruments Corporation 4-3 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
You must observe certain rules and restrictions in a DLL you want to use with LabWindows/CVI. If you experience problems using a DLL in LabWindows/CVI, you might have to contact the developer of the DLL to obtain modifications.
Because LabWindows/CVI is a 32-bit application, special glue code is required to communicate with a 16-bit DLL. For some DLLs, LabWindows/CVI can automatically generate this glue code from the include file when loading the DLL. For other DLLs, you have to modify the glue source code and compile it with Watcom into a
The normal way of communicating with a DLL is by calling fun ctions in the DLL. However, cases exist where you must use other communication methods. The most typical case is that of an interrupt service routine in a DLL that notifies the application when an interrupt occurs. This is done through a callback function. Also, LabWindows/CVI can recognize messages posted by a DLL through the Windows Application Programming Interface (API) function
PostMessage and initiate a callback function.
Helpful LabWindows/CVI Options for Working with DLLs
LabWindows/CVI provides two options that can be helpful when working with DLLs. The options can be found in the Run Options menu of the Project window:
Enable the Check Disk Dates Before Each Run option when you iteratively modify a DLL or DLL glue code file and run a LabWindows/CVI test program that calls into the DLL. By enabling the Check Disk Dates Before Each Run option, you ensure that you link the most recent version of the DLL and DLL glue code into your pro gram . You can leave this option enabled at all times. The only penalty is a small delay each time you build or run the project.
By default, LabW indows/CVI does not unload and relo ad DLLs between each execution of your program. This eliminates the delay in reloading the DLLs b efore each run. It allows the DLLs to retain state information between each run. If, ho wever , you use a DLL that does not work correctly across multiple program executions, enable the Reload DLLs Before Each Run option.
.obj or .lib file.

DLL Rules and Restrictions

T o call into a 16- bit DLL from LabW indows/CVI 3 2-bit code, you must obs erve the follo wing rules and restrictions for DLL functions:
In the DLL header file, change all references to
In the DLL header file, change all references to
unsigned short.
You can declare the functions in the DLL as
You cannot use variable argument functions.
LabWindows/CVI Programmer Reference Manual 4-4
int into references to short. unsigned or unsigned int to
PASCAL or as CDECL.
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
You can use the ar g ument types char, unsigned char, int, unsigned int, short,
unsigned short, long, unsigned long, float, and double, as well as pointers to
any type, and arrays of any type. You can use typedefs for these types.
You can use the return types
short, unsigned short, long, and unsigned long, as well as pointers to any type.
void, char, unsigned char, int, unsigned int,
You can use typedefs for these types.
You can use the return types float and double only if the DLL is created with a Microsoft C compiler, and the functions returning floats or double are declared with the
cdecl calling convention. You do not have to modify the glue code generated for
functions that return float or double values.
In the DLL header file, enum sizes must be consistent between LabW indows/CVI and the compiler for the DLL.
typedef enum { No_Error, Device_Busy, Device_Not_Found } ErrorType;
The size of ErrorType is 2 bytes in Visual C++, whereas it is 1 byte in LabWindows/CVI. To force LabWindows/CVI to treat
ErrorType as 2 bytes, add
another enum value explicitly initialized to a 2-byte value, such as the following.
ErrorType_Dummy = 32767
If the DLL you are using perfo rms DMA on a buf fer you pas s to it, you mi ght experi ence a problem. The DLL might attempt to lock the buf fer in memory by calling the Windows SDK function Watcom
Write the DLL so that if
GlobalPageLock. GlobalPageLock fails on buffers allocated with the
malloc function that LabWindows/CVI uses in 32-bit mode.
GlobalPageLock fails, the DLL attempts to lock the buffer
with the following code:
int DPMILock (void *buffer, unsigned long size) {
DWORD base; unsigned sel, offset; union _REGS regs; sel = SELECTOROF(buffer); offset = OFFSETOF(buffer); base = GetSelectorBase(sel); base = base+offset;
regs.x.ax = 0x600; /* DPMI lock memory function */ regs.x.bx = HIWORD(base); regs.x.cx = LOWORD(base); regs.x.di = LOWORD(size);
©
National Instruments Corporation 4-5 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
regs.x.si = HIWORD(size); int86(0x31, ®s, ®s); return regs.x.cflag;
}
After the DMA is complete, you must unlock the buffer . You can unlock the buffer using
DPMILock function, if you set regs.x.ax to 0x601, instead of 0x600.
the
If you compile the DLL with the
/FPi is the default), the DLL uses the WIN87EM.DLL floating point emulator.
( LabWindows/CVI does not use following strategy in the DLL to prevent conflicts:
1. Structure the code so that all functions that perform any floating-point math have known entry and e xit po ints. Ide a lly, spe cify a p ar ticula r set of expo rted entry points as the only ways into the floating-point code.
2. Call the Windows SDK function previous signal handler in a function pointer.
3. If the DLL has its own exception handler, call signal handler.
4. Perform the floating-point math.
5. Upon exiting through one of the well-defined DLL exit points, call the Windows SDK function the DLL’s use of
typedef void (*LPFNSIGNALPROC) (int, int);
FPTerm to restore the previous exception hand ler and termina te
WIN87EM.DLL.
/FPi or /FPc switches or with no /FP switches
WIN87EM.DLL. If the DLL uses WIN87EM.DLL, use the
FPInit in each of these entry points. Store the
signal to register the DLL’s own
/* prototypes for functions in WIN87EM.d11 */ LPFNSIGNALPROC PASCAL_FPInit (void); VOID PASCAL_FPTerm (LPFNSIGNALPROC);
void DllFunction (void) {
LPFNSIGNALPROC OldFPHandler;
/* save the floating point state, and setup the */ /* floating point exception handler for this DLL. */ OldFPHandler = _FPInit (); signal ( SIGFPE, DLLsFPEHandler); /* optional */ . . .
LabWindows/CVI Programmer Reference Manual 4-6
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
/* perform the computations */ . . . /* restore the floating point state */ _FPTerm (OldFPHandler);
}
Note
If you use Microsoft C to build the DLL, you might get a linker error for an undefined symbol versions 7.00 and later. Include the following dummy function in your DLL to fix this error. Also, when linking to the DLL, specify as the first library to be linked.
void _acrtused2 (void) { }

DLL Glue Code

Because LabWindows/CVI is a 32-bit application, it does not use 16-bit import libraries or import statements in module definition files. Instead, LabWindows/CVI uses 32-bit DLL glue code. In some cases, it is sufficient to use glue code that LabWindows/CVI automatically generates when it loads the DLL. However, you cannot use this method in the following cases:
The DLL requires special interface functions compiled outside of the DLL.
You expect to pass arrays bigger than 64 K to functions in the DLL.
You pass a pointer to a function in the DLL, and the DLL uses the pointer after the function returns. For example, you pass an array to a function that starts an asynchronous I/O operation. The function returns immediately , but the DLL continues to oper ate on the array .
Y ou pass a f unction pointer to the DLL, and the DLL calls the f unction later . For example, the DLL makes a direct callback into 32-bit code.
Y ou pass to the DLL a pointer that points to other pointers. Two examples of pointers that point to other pointers are an array of pointers and a structure pointer with pointer members.
The DLL returns pointers as return values or through reference parameters.
The DLL exports functions by ordinal value only.
_acrtused2. This error occurs only in Microsoft C
WIN87EM.LIB
If your DLL falls into any of these categories, refer to the DLLs That Canno t Use Glue Co de
Generated at Load T ime section of this chapter for details on how to proceed. Other wise, refer
to the DLLs That Can Use Glue Code Generated at Load Time section, also in this chapter.
©
National Instruments Corporation 4-7 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
DLLs That Can Use Glue Code Generated at Load Time
If your DLL can use glue code generated at load time, LabWindows/CVI automatically generates the glue code based on the contents of the it loads it.
.h file it associates with the DLL when
Any functions declared as
PASCAL in the .h file. LabWindows/CVI ignores the PASCAL keyword except when
PASCAL, pascal, or _pascal in the DLL should be declared as
generating the glue code. Use only standard ANSI C keywords in the
exception to this rule.) For example, do not use
Note
You can create an object module that contains the glue code. If you do so,
.h file. (The keyword PASCAL is the only
far, near, or huge.
LabWindows/CVI can load the DLL faster because it does not have to regenerate and recompile the glue code. To create the object module, load the
.h file into a
Source window and select Options»Generate DLL Glue Object. If the DLL pathname is listed in the project, replace it with the object module file. If the DLL is not listed in the project, but is associated with a module is in the same directory as the
.fp file.
.fp file, make sure the object
DLLs That Cannot Use Glue Code Generated at Load Time
If your DLL cannot use glue code generated at load time, you must generate a glue code source file from the DLL include file using the Generate DLL G lue S o ur ce command from the Options menu of a Source window. You must then compile the glue code using the Watcom compiler to create a
.obj or .lib file to be loaded with the DLL. If you also have
interface functions that must exist outside the DLL, you must combine them with the glue code to form the
.obj or .lib file.
Loading a DLL That Cannot Use Glue Code Generated at Load Time
If you have a 32-bit Watcom comp il ed .obj or .lib file that contains glue code for a DLL, LabWindows/CVI must load the
x.dll and x.obj in your program, add x.obj to the project. Do not add x.dll to the
project. The
.obj or .lib file causes LabWindows/CVI to load the .dll.
.obj or .lib file first. For instance, if you want to use
.obj or .lib file must contain the glue code for the DLL. It is the presen ce of th e glue
The code that indicates to LabWindows/CVI that a
When LabWindows/CVI loads the first looks for the
.dll, LabWindows/CVI looks fo r it us ing t he standar d Win dows DLL sear ch algori thm.
the
LabWindows/CVI Programmer Reference Manual 4-8
.dll in the same directory as the .obj or .lib file. If it cannot find
.obj or .lib file and finds that it contains glue code, it
.dll is associated with the .obj or .lib file.
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
Also, you can create a .pth file in the same directory as the .obj or .lib file with the same base name. The
.pth file must contain a simple filen ame or a full path name of the DLL. If it
is a simple filename, LabWindows/CVI uses the standard Windows DLL search algorithm.
Rules for the DLL Include File Used to Generate Glue Source
You can generate the DLL glue source file by opening the .h file for the DLL in a Source window and selecting Generat e DLL Glue Source fro m the Options menu. Th is command prompts you for th e name of a base name as the
.h file. You must modify this .c file as this section describes and compile
it using the Watcom compiler. Refer to the Using 32-Bit Watcom Compiled Modules
under Windows 3.1 section of this chapter for information on how to use the Watcom
compiler with LabWindows/CVI.
.h file. It puts the glue code in a .c file with the same path and
If any of the functions in the DLL are declared as declare them as ignores the
PASCAL in the .h file you use to generate the glue code. LabWindows/CVI
PASCAL keyword exce pt for the purposes of generating the glue code. The stub
function in the glue code is not declared as
PASCAL, pascal, or _pascal, you must
PASCAL. If you include this .h file in the glue
code, the Watcom compiler flags as an error the inconsistency between the declaration of the function in the
.h file and the definition of the stub function. If you include it in other modules
you compile under Watcom, calls to the function erroneously compile as if the function were
PASCAL. You have two o ptions:
Have two se parate Use the one that does include the
Use conditional compilation so that Watcom ignores the
.h files, one that includes the PASCAL keyword and one that does not.
PASCAL keyword to generate the glue code only.
PASCAL macro when it
compiles.
Only use standard ANSI C keywords in the exception to this rule. For example, do not use
.h file. The keyword PASCAL is the only
far, near, or huge.
If the DLL Requires a Support Module outside the DLL
Support modules contain special interface functions that the DLL uses but that exist outside of the DLL. If you are unsure whether the DLL requires a support module, try to build a project in LabWindows/CVI with the DLL in the project list. If link errors exist in the form of unresolved references, the DLL requires special interface functions. Get the source code for the interface functions, add it to the glue code, and compile using the Watcom compiler.
If You Pass Arrays Bigger Than 64 K to the DLL
If you pass the DLL any arrays bigger than 64 K, you must modify the glue code source f ile. For example, suppose you have a function in the DLL with the following prototype:
long WriteRealArray (double realArray[], long numElems);
©
National Instruments Corporation 4-9 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
In the glue code generated by LabWindows/CVI, there is a declaration of WriteRealArray like that shown in the following example.
long WriteRealArray (double realArray[], long numElems) {
long retval; unsigned short cw387; cw387 = Get387CW(); retval = (long) InvokeIndirectFunction (__static_WriteRealArray, realArray,
Set387CW (cw387); return retval;
}
numElems);
Note
The lines of code referencing cw387 are necessary only if the DLL function performs floating point opera tions. They are innocuous and execute quickly, so LabWindows/CVI adds them to the glue code automatically. If the DLL function does not perform floating point operations, you can remove these lines.
realArray can be greater than 64 K, you must modify the interface routine as shown.
If
long WriteRealArray (double realArray[], long numElems) {
long retval; unsigned short cw387; DWORD size; DWORD alias;
size = numElems * sizeof(double); if (Alloc16BitAlias (realArray, size, &alias) <0) return < cw387 = Get387CW(); retval = (long) InvokeIndirectFunction (__static_WriteRealArray, alias,
Set387CW (cw387); Free16BitAlias (alias, size); return retval;
}
error code
>;
numElems);
LabWindows/CVI Programmer Reference Manual 4-10
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
You must also modify the call to GetIndirectFunctionHandle for WriteRealArray as shown in the following code:
if (!(__static_WriteRealArray = GetIndirectFunctionHandle (fp, INDIR_PTR, INDIR_WORD, INDIR_ENDLIST)))
by changing INDIR_PTR to INDIR_DWORD.
If the DLL Retains a Buffer after the Function Returns (an Asynchronous Operation)
If the DLL retains a buffer after the function returns, you must modify the glue code source file. Suppose two functions exist.
WriteRealArray, except that it returns before it completes writing the real array. ClearAsyncWrite terminates the asynchronous I/O. The glue code interface functions for WriteRealArrayAsync and ClearAsyncWrite should be modified to resemble the
following example.
static DWORD gAsyncWriteAlias, gAsyncWriteSize;
long WriteRealArrayAsync (double realArray[], long numElems) {
long retval; unsigned short cw387; DWORD size; DWORD alias;
WriteRealArrayAsync operates just like
size = numElems * sizeof(double); if (Alloc16BitAlias (realArray, size, &alias) < 0) return < cw387 = Get387CW(); retval = (long) InvokeIndirectFunction (__static_WriteRealArrayAsync, alias,
Set387CW (cw387); if (IsError (retval)) /* replace with macro to check if */
Free16BitAlias (alias, size); else { gAsyncWriteAlias = alias; gAsyncWriteSize = size; } return retval;
}
©
National Instruments Corporation 4-11 LabWindows/CVI Programmer Reference Manual
error code
>;
numElems);
/* retval is error */
Chapter 4 Windows 3.1 Compiler/Linker Issues
long ClearAsyncWrite (void) {
/* because this does no floating point, you can remove */ /* the cw387 code */ long retval;
retval = (long) InvokeIndirectFunction(__static_ClearAsyncWrite); if (!IsError (retval)) /* replace with macro to check if */
if (gAsyncWriteAlias != 0) {
Free16BitAlias (gAsyncWriteAlias,gAsyncWriteSize); gAsyncWriteAlias = 0; gAsyncWriteSize = 0;
}
return retval;
}
You can terminate LabWindows/CVI programs in the middle of execution and then re-run them. When you terminate the program, you should also terminate the asynchronous I/O. You can arrange to be notified of changes in the run state by including a function with th e name
RunStateChangeCallback in the .obj or .lib file associated with the DLL. You can add
this function to the glue code file. Refer to the Notification of C ha nges in Run State section of Chapter 2, Using Loadable Compiled Modules, of this manual for a complete description of the run state change notification. In the examp le we have b een discussing, you shou ld add the following code.
#include "libsupp.h" void CVICALLBACK __RunStateChangeCallback (int newState) {
if (newState == kRunState_Stop) ClearAsyncWrite ();
}
/* retval is error */
If the DLL Calls Directly Back into 32-Bit Code
If the DLL calls directly back into 32-bit code, you must modify the glue code source file. You can call functions defined in 32-bit source code directly from a DLL. Although this method is not as straightforward as Windows messaging, it is not subject to the latencies of Window messaging. For more information about Windows messaging, refer to the
Recognizing Windows Messages Passed from a DLL section of this chapter.
Note
LabWindows/CVI Programmer Reference Manual 4-12
If you need direct callbacks to occur at interrupt time because the latency of Windows messaging is interfering with your application, contact Na tional Instruments for assistance.
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
You cannot pass pointers to 32-bit functions directly into 16-bit DLLs. The Windows SDK interface for this is very complex. Generate DLL Glue Source does not generate this code for you. You must write your o wn glue code f or passing fu nction point ers to and fro m a DLL, and add it to the file that Generate DLL Glue Source generates.
Suppose a DLL contains the following functions:
long (FAR*savedCallbackPtr) (long); long FAR InstallCallback(long (FAR*callbackPtr) (long)) {
savedCallbackPtr = callbackPtr;
} long InvokeCallback(long data) {
return (*savedCallbackPtr)(data);
}
After you use the Generate DLL Glue Source command to generate the glu e code fo r these functions, you must modify the code as follows.
Note Because direct callbacks must be declared far, and LabWindows/CVI cannot
compile it to the DLL. This
far functions, you must declare a far function in the glue code and pass
far function calls the actual user function.
#undef MakeProcInstance /* Use version that does not */
/* convert pointer. */
#undef FreeProcInstance /* Use version that does not */
/* convert pointer. */
typedef struct { /* Holds resources required to register*/
/* the callback. */ int UserDefinedProcHandle; CALLBACKPTR proc16; FARPROC proc16Instance;
} CallbackDataType; static CallbackDataType CallbackData;
static long (*UsersCallback)(long);
/* Define a 32-bit far callback whose address is passed to */ /* the DLL. It calls your function using function pointer */ /* stored in UsersCallback. */
©
National Instruments Corporation 4-13 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
static long FAR CallbackHelper(long data) {
return (*UsersCallback)(data);
}
/* Modified glue code for the function that installs the */ /* callback. */ long InstallCallback(long (*callback)(long)) {
long retval; unsigned short cw387;
UsersCallback = callback; /* Store CVI 32-bit pointer */
/* Create a 16-bit thunk for the 32-bit far function */ /* CallbackHelper */
if ((CallbackData.UserDefinedProcHandle =
return FALSE;/* Too many callbacks installed */
/* or handles not freed. */
/* in static variable. */
GetProcUserDefinedHandle()) == 0)
if (DefineUserProc16(CallbackData.UserDefinedProcHandle,
(PROCPTR) CallbackHelper, UDP16_DWORD,
UDP16_CDECL, UDP16_ENDLIST))
goto failed;
if (!(CallbackData.proc16 =
GetProc16((PROCPTR)CallbackHelper,
CallbackData.UserDefinedProcHandle)))
goto failed;
CallbackData.proc16Instance =
MakeProcInstance(CallbackData.proc16,
GetTaskInstance());
cw387 = Get387CW(); retval = (long) InvokeIndirectFunction(__static_InstallCallback,
CallbackData.proc16Instance); Set387CW(cw387); return retval;
LabWindows/CVI Programmer Reference Manual 4-14
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
failed:
FreeCallbackResources(); return FALSE;
}
/* Call this function after unregistering the callback. */ void FreeCallbackResources(void) {
if (CallbackData.proc16Instance) {
FreeProcInstance(CallbackData.proc16Instance);
CallbackData.proc16Instance = 0; } if (CallbackData.proc16) {
ReleaseProc16(CallbackData.proc16);
CallbackData.proc16 = 0; } if (CallbackData.UserDefinedProcHandle) {
FreeProcUserDefinedHandle(CallbackData.UserDefinedProcHandle);
CallbackData.UserDefinedProcHandle = 0; }
}
If the DLL Returns Pointers
DLLs return pointers that fall into the following two classes.
Pointers to memory that LabW indows/CVI allocates, that you pass into the DLL, an d that the DLL later returns
You must map these pointers back into normal 32-bit pointers that you can use in LabWindows/CVI code. Use the function
Pointers to memory that a DLL allocates Because these pointers point to memory that is not in the LabWindo ws/CVI flat address
space, you cannot map them back into the normal 32-bit point ers that LabW indo ws/CVI uses. You can access them in Watcom object code by first converting them to 32-bit far pointers using the function
MK_FP32.
To access them in LabWindows/CVI source code you must copy the data into a buffer you allocate in LabW ind o ws/C VI. Notice t hat you canno t pass 16- or 32- bit far poi nt ers to LabWindows/CVI library functions, and that LabWindows/CVI does not provide access to the Watcom string and memory buffer manipulation functions that take far pointers as arguments. You must write the loops to copy the data.
©
National Instruments Corporation 4-15 LabWindows/CVI Programmer Reference Manual
MapAliasToFlat to convert these pointers.
Chapter 4 Windows 3.1 Compiler/Linker Issues
Case 1
Assume the DLL has the following function:
char *f(char *ptr) {
sprintf(ptr, "hello"); return ptr;
}
Then assume that a program in LabWindows/CVI uses the function f as follows:
char buffer[240]; char *bufptr; bufptr = f(buffer); printf("%s", bufptr);
You would ha ve to modify the glue code as shown here:
char * f(char *ptr) {
char * retval; unsigned short cw387;
cw387 = Get387CW(); retval = (char *) InvokeIndirectFunction(__static_f, ptr); Set387CW(cw387); retval = MapAliasToFlat(retval); /* Add this line to */
return retval;
}
/* glue code. */
Case 2
Assume the DLL has the following function:
char *f(void) {
char *ptr;
ptr = malloc(100); sprintf(ptr, "hello"); return ptr;
}
LabWindows/CVI Programmer Reference Manual 4-16
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
Then assume that a program in LabWindows/CVI uses the function f as follows:
char *bufptr; bufptr = f(); printf("%s", bufptr);
You would ha ve to modify the glue code as shown here:
char * f(char *ptr) {
char *retval; unsigned short cw387; char *ptr, *tmpPtr, _far *farPtr32, _far *tmpFarPtr32; int i;
cw387 = Get387CW(); retval = (char *) InvokeIndirectFunction(__static_f, ptr); Set387CW(cw387);
/* convert the 16 bit far pointer to a 32 bit far pointer*/
farPtr32 = MK_FP32(retval);
tmpFarPtr32 = farPtr32;
/* Calculate the length of the string. Cannot call strlen*/ /* because it does not accept far pointers. */
i = 0 while (*tmpFarPtr32++)
i++;
/* Allocate buffer from CVI memory and copy in data. */ if ((ptr = malloc(i + 1)) != NULL) {
tmpFarPtr32 = farPtr32; tmpPtr = ptr;
while (*tmpPtr++ = *tmpFarPtr32++); } return ptr;
}
©
National Instruments Corporation 4-17 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
If a DLL Receives a Pointer that Points to Other Pointers
Assume the following DLL functions:
int f(char *ptrs[]); struct x {
char *name; }; int g(struct x *ptr);
For the function f, the glue code that LabWindows/CVI generates converts the pointer to the
ptrs to a 16-bit far pointer when you pass it to the DLL function, but does not convert
array the pointers inside the array glue code that LabWindows/CVI generates converts the po inter to the structure ( the pointer inside the structure (
If your DLL has functions with these types of parameters, then your DLL cannot use glue code automatically generated at load time. You can use the Generate DLL Glue Source command to generate glue code and th en modify it in the following manner.
1. Before the call to
a. Save the hidden pointer in a local variable.
b. Replace the hidden pointer with a 16-bit alias by calling
2. After the call to
a. Free the 16-bit alias by calling
b. Restore the hidden pointer with the value you saved in step 1.
(ptrs[0], ptrs[1], ...). Similarly, for the function g, the
InvokeIndirectFunction,
InvokeIndirectFunction,
ptr), but not
name).
Alloc16BitAlias.
Free16BitAlias.
For the functions
f and g, the glue code that LabWindows/CVI generates looks like the
following excerpt:
int f(char **ptrs) {
int retval;
unsigned short cw387;
cw387 = Get387CW();
retval = (int) InvokeIndirectFunction(__static_f, ptrs);
Set387CW(cw387);
return retval; } int g(struct x *ptr) {
int retval;
unsigned short cw387;
LabWindows/CVI Programmer Reference Manual 4-18
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues
cw387 = Get387CW(); retval = (int) InvokeIndirectFunction(__static_g, ptr); Set387CW(cw387); return retval;
}
After you make the necessary changes, the code should appear as follows:
/* Assume NUM_ELEMENTS is the number of pointers in the input */ /* array. Assume ITEM_SIZE is the number of bytes pointed */ /* to by each pointer. If you do not know ITEM_SIZE, but you */ /* know that it is 64K or less, you can use 64K as ITEM_SIZE. */ int f(char **ptrs) {
int retval; unsigned short cw387; int i; char *savedPointers[NUM_ELEMENTS];
/* change the pointers to 16-bit far pointers */ for (i = 0 ; i < NUM_ELEMENTS; i++) {
savedPointers[i] = ptrs[i]; if (Alloc16BitAlias(ptrs[i], ITEM_SIZE, &ptrs[i]) == -1) {
/* failed to allocate an alias; restore */ /* pointers. */ while (i--)
ptrs[i] = savedPointer[i];
return <
} } cw387 = Get387CW(); retval = (int) InvokeIndirectFunction(__static_f, ptrs); Set387CW(cw387);
error code
>;
/* Restore the pointers. */ for (i = 0 ; i < NUM_ELEMENTS; i++) { Free16BitAlias(ptrs[i], ITEM_SIZE); ptrs[i] = savedPointers[i]; } return retval;
}
©
National Instruments Corporation 4-19 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
int g(struct x *ptr) {
int retval; unsigned short cw387; char *savedPointer;
savedPointer = ptr->name; if (Alloc16BitAlias(ptr->name, ITEM_SIZE, &ptr->name) == -1)
return <
cw387 = Get387CW(); retval = (int) InvokeIndirectFunction(__static_g, ptr); Set387CW(cw387);
Free16BitAlias(ptr->name, ITEM_SIZE); ptr->name = savedPointer; return retval;
}
error code
DLL Exports Functions by Ordinal Value Only
If your DLL does not export its functions by name, but by ordinal number only, you must modify the the function as the second parameter, pass where number for the function
GetProcAddress f unction calls in the glue code. I nstead of pass ing the name of
OrdinalNumber
is the ordinal number for the function. For example, if the ordinal
InstallCallback is 5, change the glue code as follows.
>;
PASS_WORD_AS_POINTER(
OrdinalNumber
),
Generated Glue Code:
if (!(fp = GetProcAddress(DLLHandle,"InstallCallback"))) {
funcname = "_InstallCallback"; goto FunctionNotFoundError;
}
Change to:
if (!(fp = GetProcAddress(DLLHandle, PASS_WORD_AS_POINTER(5)))) {
funcname = "_InstallCallback"; goto FunctionNotFoundError;
}
LabWindows/CVI Programmer Reference Manual 4-20
©
National Instruments Corporation
Chapter 4 Windows 3.1 Compiler/Linker Issues

Recognizing Windows Messages Passed from a DLL

The normal way of communicating with a DLL is to call functions in the DLL. However, cases exist where other communication methods are necessary. The most typical case is that of an interrupt service routine in a DLL that must notify the application that the interrupt occurred. In cases like this, you must communicate with the DLL thr ough a callback fun ction.
LabWindows/CVI recognizes messages posted by a DLL through the Windows SDK function for hardware interrupts, but it is subject to the latency associated with Windows messaging. LabWindows/CVI uses
GetCVIWindowHandle to recognize Windows messages from a DLL. You can call these
functions from a module compiled in Watcom or from source code. For complete information on these functions, refer to the function descriptions in Chapter 4,
User Interface Library Reference, of the LabWindows/CVI User Interface Reference Manual.
PostMessage, and can initiate a user callback function. This method is useful
RegisterWinMsgCallback, UnRegisterWinMsgCallback, and
To use these functions, call
RegisterWinMsgCallback and GetCVIWindowHandle. Pass
their return values, the message number and the window handle, to the DLL. When the DLL sends a message, it calls
PostMessage with these values. When LabWindows/CVI receives
the message, it calls the callback function.
Note
LabWindows/CVI can receive the message only when it is processing events.
LabWindows/CVI processes events when it is waiting for user input. If the
program you run in LabWindows/CVI does not call
GetUserEvent, or scanf, or if it does not return from a User Interface Library
callback, events will not be processed. You can remedy this in the program by
periodically calling the User Interface Library function
Creating 16-bit DLLs with Microsoft Visual C++ 1.5
Be sure to consider the following issues or project options when you create a DLL with Microsoft Visual C++ 1.5:
Every function you call fr om out side the DLL must be data segment into the DS register. The fun ction mu st load the DS register if you want to use any non-local variables in a function.
Use the large or huge memory model. The savings you gain by using smaller memory models is not worth having to use the
far keyword throughout your code. This project
option is in Compiler»Memory Model»Segment Setup.
You can make the compiler load the data segment into the DS register automatically by using the SS!=DS, DS loaded on function entry project option in Compiler»Memory Model»Segment Setup.
If you try to use the optimize entry code option ( Compiler»Windows»Prolog/Epilog»Generate Prolog/Epilog For, it conflicts with the
far, exp orted, and must load the
/GD), by selecting
RunUserInterface,
ProcessSystemEvents.
©
National Instruments Corporation 4-21 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
/Au option. Y ou can either not use this option by setting it to None, or insert __loadds
in front of every function you export from the DLL.
You can mak e the compiler e x port a f unction b y insertin g type and the function name, or b y addin g the funct ion name to the e xports sect ion of t he
.def file.
If you add the fu nction name t o the exp orts s ection of the . the name to all caps if you use the underscore if you use the
CDECL calling convention.
PASCAL calling convention, or pre-append an
Byte align structure members by choosing 1 B yte for the Options»Pr oj ect»Comp ile r» Code Generation»Struct Member Byte Alignment.

Creating 16-bit DLLs with Borland C++

Consider the following issues or project options when you create a DLL with Borland C++ 4.x:
Every function you call fr om out side the DLL must be data segment into the DS register. The fun ction mu st load the DS register if you want to use any non-local variables in a function.
Use the large or huge memory model. The savings you gain by using smaller memory models is not worth having to use the option is in 16-bit Compiler»Memory Model»Mixed Model Override.
You can make the compiler load the data segment into the DS register by setting the project option 16-bit Compiler»Memory Model»Assume SS E quals DS to Never, or by inserting
_loadds in front of every function you export from the DLL.
You can make the compiler export a function by inserting type and the function name, ad ding t he fun ction n ame to the e xport s secti on of the file, or setting the option 16-bit Compiler»Entry/Exit Code»Windows DLL, all functions exportable.
If you add the funct ion name to the ex ports sectio n of the the name to all caps if you use the underscore if you use the
CDECL calling con vention. Also, set the Generate Underscores
option in Compiler»Compiler Output.
Turn off the Allocate Enums as Ints option in Compiler»Code Generation.
Set the Data Alignment options to Byte in 16-bit Compiler»Processor.
Turn off the Case Sensitive Link and Case Sensitive Exports and Imports options in the Linker»General.
Do not use the L i nker Goodies optio ns in Linker»16-bit Linker.
far keyword throughout your code. This project
PASCAL calling convention, or pre-append an
__export between the return
def file, remember to con vert
far, exp orted, and must load the
_export between the return
.def
.def file, remember to convert
LabWindows/CVI Programmer Reference Manual 4-22
©
National Instruments Corporation

DLL Search Precedence

LabWindows/CVI finds a DLL file in the following ways for Windows 3.1:
•If the
•If the
.dll file is associated with a .fp file, LabWindows/CVI uses the following search
precedence to find the DLL.
1. If a
.pth file with the same full path name as the .fp file is in the project,
LabWindows/CVI uses the standard Windows DLL search algorithm. The file must contain the name o f the contain an absolute path or a simple filename.
2. If a
.dll file with the same full path name as the .fp file is in the project,
LabWindows/CVI uses th e ab solute path of the
.dll file.
the
3. If a
.pth file with the same base name as the .fp file is in the same directory as
.fp file and a .lib or .obj file of the same base name does not exist in the
the same directory, La bWindow s/CVI use s th e stan dar d Window s D LL s earc h algorithm. The
mystuff.dll. It must not contain any directory names or slashes .
4. If a
5. If a
.dll file with the same base name as the .fp file is in the same directory as
.fp file, LabWindows/CVI loads the .dll file as long as no .lib, .obj,
the
.pth file of the same base name appears in the same directory.
or
.pth or .dll file does not appear in the same directory as the .fp file,
LabWindows/CVI uses th e stan dard Windo ws sear ch a lgor ithm to loo k for a DLL with the same base name as the name is in the
PATH environment variable, LabWindo ws/CVI finds it.
your
DLLs for VXIplug&play drivers are not in the same directory as the directory that contains the DLL is listed in the Step 5 makes it easier for you to use VXIplug&play instrument driver DLLs in LabWindo ws /CVI for Windows 3.1.
.dll file is not associated with a .fp file, LabWindows/CVI uses the following
search precedence to find the DLL:
1. If a
.pth file is in the project list, LabWindows/CVI uses the standard Windows
DLL search algorithm. The such as
2. If the
mystuff.dll. It must contain an absolute path or a simple filename.
.dll file is in the project list, then LabWindows/CVI uses the absolute
pathname to find the
Chapter 4 Windows 3.1 Compiler/Linker Issues
.pth
.dll file, such as mystuff.dll. It must
.dll file in the p ro jec t to lo ad
.pth file must contain the name o f th e .dll file, such as
.fp file. Thus, if a DLL with the same base
windows or windows\system directory or a directory listed in
.fp files, but the
PATH environment variable. Therefore,
.pth file must contain the name of the .dll file,
.dll file.
©
National Instruments Corporation 4-23 LabWindows/CVI Programmer Reference Manual
Chapter 4 Windows 3.1 Compiler/Linker Issues
If you call LoadExternalModule on the .dll file, then – If you specify it with an absolute pathname, LabWindows/CVI loads that file. – If you specify it with a relative pathname, LabWindows/CVI searches for the
file in the following places and order indicated.
1. In the project list.
2. In the directory in which the project file is located.
3. Among other modules already loa ded.
4. In the directories specified in the documentation for the Windows SDK
LoadLibrary function. In this case, the include file for the DLL must be in
the project or in one of the includ e paths y ou spec ify in the I nclude Paths command in the Options menu of the Project window.
.dll
LabWindows/CVI Programmer Reference Manual 4-24
©
National Instruments Corporation
UNIX Compiler/Linker Issues
This chapter describes the kinds of compiled modules available under LabWindows/CVI for UNIX and includes programming guidelines for modules you generate with external compilers.

Calling Sun C Library Functions

You can call functions in the Sun Solaris C libraries from source code in LabWindows/CVI. LabWindows/CVI automatically links your program to the following static libraries, located
/usr/lib directory, when you build the project.
in the
5
Solaris 1: Solaris 2: libsocket.a, libnsl.a, libintl.a, libm.a, libc.a When you create a standalone executable, LabWindows/CVI invokes the Sun Solaris link
editor ( libraries. By default, the Sun Solaris link editor uses the dynamic versions of the libraries. LabWindows/CVI passes the following linking options to the Sun Solaris link editor:
Solaris 1: Solaris 2: -lsocket -lnsl -lintl -lm -lthread -lc In general, you can use the header files that Sun provides for these libraries in the
/usr/include directory . For the ANSI C functions, ho we ver , use the header files that come
with LabWindows/CVI.
libm.a, libc.a
ld) to link your program to the LabWindows/CVI dynamic library and to the system
-lm -ldl -lc

Restrictions on Calling Sun C Library Functions

You cannot call any Sun C Library function that uses data types incompatible with the LabWindows/CVI compiler or libraries. In particular, you must not call functions that use the
long double data type. In LabWindows/CVI the long double data type has 8 bytes, but the
Sun libraries expect a 16-byte object. Under Solaris 2, you must not call any function that uses the
LabWindows/CVI does not recognize this non-ANSI type.
long long data type.
©
National Instruments Corporation 5-1 LabWindows/CVI Programmer Reference Manual
Chapter 5 UNIX Compiler/Linker Issues

Using Shared Libraries in LabWindows/CVI

In the LabWindows/CVI development environment, you can link your programs to static libraries, but not to shared libraries. If you hav e to use a shared library, you must use the Sun Solaris linker (
LabWindows/CVI Libraries section later in this chapter for more information on using
external compilers and the Sun linker. If you have both shared and static versions of a library, you can develop and debug your
application in the LabWindows/CVI de velopment en vironment using the static version of the library . You can then create your final executable with the Sun linker using the shared version of the library.

Using dlopen

The Sun Solaris dlopen function allows you to load shared libraries from your program dynamically. Although this function can work in some cases when running in LabWindows/CVI, it can make LabWindows/CVI unstable. If you use libraries in a program you run in LabWindows/CVI, the shared libraries might link to the system libraries the LabWindows/CVI environment uses. As a result, functions in the shared library might modify the LabWindows/CVI environment and cause unpredictable behavior.
ld) to build your application. Refer to the Creating Executables that Use the
dlopen to load shared
The LabWindows/CVI Run-Time Engine as a Shared Library
The LabWindo ws/CVI dev elopment en vironment contains many b uilt-in libraries such as the User Interface Library and Utility Library. LabWindows/CVI also provides these lib raries in the form of a standalone shared library called the LabWindows/CVI Run-time Engine. All executables that call LabWindows/CVI library functions use the Run-time Engine shared library. This is true whether you build the executable in the LabWindows/CVI development environment or with an external compiler and the Sun Solaris linker.
LabWindows/CVI Programmer Reference Manual 5-2
©
National Instruments Corporation
Creating Executables that Use the LabWindows/CVI Libraries
You can build executables that use the LabWindows/CVI libraries in two ways:
You can build an executable in the LabWindows/CVI development environment by
selecting the Create Standalone Executable command in the Build menu of the Project window. When you do so, LabWindows/CVI invokes the Sun Solaris linker ( your programs to the Run-time Engine shared library.
You can use an external compiler and linker to create an executable that uses the
Run-time Engine shared library. Use the Gen erate Makefile comman d in the Build menu of the Project window to generate a UNIX makefile that corresponds to the currently loaded project and libraries. The makefile invokes an external compiler to compile your source files, and then it invokes the Sun Solaris linker ( the Run-time Engine shared library.

Compatible External Compilers

Y o u can use the following external ANSI C compilers to compile source files for linking with the LabWindows/CVI Run-time Engine shared library.
GNU C Compiler (
Sun C Compiler (
gcc)
cc and acc)
Chapter 5 UNIX Compiler/Linker Issues
ld) to link
ld) to link the compiled files with
Note
Under Solaris 2.4, when linking the LabWindows/CVI Shared Library with external ANSI C compiler, the compiler displays a warning that states the shared library has an invalid type. You can ignore this warning.
Static and Shared Versions of the ANSI C and Other Sun Libraries
When you build a project for execution in the LabWindows/CVI development environment, LabWindows/CVI links your program to the static versions of the Sun Solaris libraries
libc.a and libm.a). On the other hand, when you create a standalone executable in the
( LabWindows/CVI development environment, LabW indows/CVI invokes the Sun Solaris link
ld) to link your program to the shared versio ns of the librar ies (libc.so and
editor (
libm.so). Similarly, when you generate a UNIX makefile by invoking the Generate
Makefile command from the Build Menu of the Project window , the makef ile contains linker
commands to use the shared versions of the libraries. Thus, when you run your programs as executables, you use a different version of the Sun
libraries (including the ANSI C library) than when you run them in the LabWindows/CVI development environment. Your program might exhi bit slightly different behavior as a standalone executable than when run in the development environment.
©
National Instruments Corporation 5-3 LabWindows/CVI Programmer Reference Manual
Chapter 5 UNIX Compiler/Linker Issues

Non-ANSI Behavior of Sun Solaris 1 ANSI C Library

The C library that comes with Sun Solaris 1 (SunOS 4.1.x) does not comply with the ANSI C standard as follows:
Some ANSI C functions are missing from the library.
Some library functions have different behavior than the ANSI standard specifies.
LabWindows/CVI corrects these problems by adding a library, replaces and supplements the Sun Solaris library as necessary. The So lari s 1 ANS I C L ibrar y
Implementation section contains mor e inform ation abou t ho w LabWindo ws/CVI prov ides an
ANSI C library o n Solaris 1.

LabWindows/CVI Implements printf and scanf

Although the Sun Solaris libraries provide the ANSI C family of functions for formatted input and output (
scanf, printf, and others), LabWindows/CVI provides special versions of
these functions for the following reasons:
The LabWindows/CVI versions of these functions provide run-time error checking not available with Sun Solaris versions.
The Sun Solaris 1 version of these functions do not comply fully with the ANSI C standard.
The Sun Solaris versions of these functions do not work with the LabWindows/CVI implementation of the long double data type.
For standalone executables, these functions come in a separate static library,
libcviprintf.a, in the lib subdirectory of the LabWindows/CVI installation directory.
When you create an ex ecutable in LabWindows/CVI, Lab Windows/CVI links you r p rog ram to this static library.

Main Function Must Call InitCVIRTE

If your program calls any functions from the LabWindows/CVI libraries, you must call
InitCVIRTE to initialize the libraries from the executable. This function takes three
arguments. The first and third arguments to this function must always be 0 for UNIX applications. The second must be the same value as the second parameter of your function.
InitCVIRTE returns 0 if it fails.
libcfix.a, that
main
You do not have to call
InitCVIRTE when you run your program in the LabWindows/CVI
development environment because LabWindows/CVI always initializes the libraries. However, if you do not call
LabWindows/CVI Programmer Reference Manual 5-4
InitCVIRTE, your executable cannot work. For this reason,
©
National Instruments Corporation
Chapter 5 UNIX Compiler/Linker Issues
National Instruments recommends that you always include source code similar to the following example in your program.
int main(int argc, char *argv[]) {
if (InitCVIRTE(0, argv, 0) == 0) {
return 1;/* Failed to initialize */ } /* your program code here */
}
If you pass NULL for the second argument to InitCVIRTE, your program might still work, but with the following limitations:
Your executable cannot accept the
-display command line argument. As a result, you
cannot specify an X display on the command line for your program to use. You still can use the
LoadPanel, LoadExternalModule, DisplayImageFile, SavePanelState, RecallPanelState, and other functions that normally use the directory of the
DISPLAY environment variable to specify a different X display.
executable to search for files, use the current working directory instead. If you run the executable from a directory other than the one that contains your executable, some of these functions might fail to find files.
Run State Change Callbacks Are Not Available in Executables
When you use a compiled module in LabWindows/CVI, you can arrange for LabWindows/CVI to notify it of a change in execution status (start, stop, suspend, resume). You do this through a function called
Changes in Run State section, in Chapter 2, Using Loadable Compiled Modules, describes
this in detail. The run state change callback capability in LabWindo ws/CVI is necessary because when you
run a program in the LabWindows/CVI development environment, it executes as part of the LabWindows/CVI process. When your program terminates, the operating system does not release resources as it does when a process terminates. LabWindows/CVI releases as many resources as it can, but your compiled module might have to do more. Also, if the program suspends for debugging purposes, your compiled module might have to disable interrupts.
When you run a standalone executable, it always ex ecutes as a separate process. Thus, the run state change callback facility is not necessary and does not work. External compilers report link errors when you define
__RunStateChangeCallback in more than one object file. If
you require a run state change callback in a compiled module that you intend to use both in LabWindows/CVI and an external compiler, National Instruments recommends that you put the callback function in a separate source file and create a library (
©
National Instruments Corporation 5-5 LabWindows/CVI Programmer Reference Manual
__RunStateChangeCallback. The Notification of
.a) instead of an object file.
Chapter 5 UNIX Compiler/Linker Issues

Using Externally Compiled Modules

In general, you can load objects compiled with the Sun compilers and the GNU gcc compiler into LabWindows/CVI, with a few restrictions.

Restrictions on Externally Compiled Modules

You can use externally compiled modules with the following restrictions:
The objects must not use any data types that are incompatible with the LabWindows/CVI compiler or libraries. Incompatible data types include the following:
long double with any Sun compilers. A Sun compiler implements long double
as a 16-byte object, but LabWindows/CVI implements it as an 8-byte object.
long long with the Solaris 2 Sun compiler. LabW indows/CVI does not support this
non-ANSI type.
Any enumeration type. Many compilers implement enumeration types with dif ferent
sizes and values.
You canno t l oad a Solaris 2 object file when you run LabWi ndows/CVI under S ol ari s 1 . However, you can load Solaris 1 objects when you run under Solaris 2.

Compiling Modules With External Compilers

Y ou can compile e xternal modules using LabW indows/CVI header files instead of the headers the compiler supplies. To compile this way, you must define the preprocessor macro
_NI_sparc_ to the value 1 for Solaris 1 or to the value 2 for Solaris 2.
When using the Sun ANSI C compiler, use the directory to the search list, as shown in the following command lines:
Solaris 1: acc -Xc -I/home/cvi/include -D_NI_sparc_=1 -c mysource.c Solaris 2: cc -Xc -I/home/cvi/include -D_NI_sparc_=2 -c mysource.c
When using the GNU compiler, use the -nostdinc flag to disable the standard include f iles and the must use the
-I flag to add the LabWindows/CVI include directory to the search list. Also, you
-ansi flag. For example, to compile the file mysource.c using
LabWindows/CVI headers under Solaris 1, use the following command line.
gcc -ansi -nostdinc -I/home/cvi/include -D_NI_sparc_=1 -c mysource.c
You might see warnings about conflicting types for the built-in functions memcmp and
memcpy, but you can ignore them.
Note
These examples assume that /home/cvi/include is the LabWindows/CVI header files directory. The actual path depends on how you install your copy of LabWindows/CVI.
LabWindows/CVI Programmer Reference Manual 5-6
-I flag to add the LabWindows/CVI include
©
National Instruments Corporation
Chapter 5 UNIX Compiler/Linker Issues
Y o u cannot use th e non-ANSI C Sun co mpiler cc because it d oes not recognize some ANSI C constructs in the head er files, such as fu nction prototypes and th e keywords
volatile.
const, void, and
Locking Process Segments into Memory Using plock()
You can use the UNIX function plock to lock the text and data segments of your program into memory. Ho wever , this function locks all segments of the LabWindows/CVI process, not just the segments associated with your program. Also, because the text segments of LabWindows/CVI programs actually reside in the data segment of the LabWindows/CVI process, you must lock both text and data segments, using lock all text into memory.
plock(PROCLOCK), in order to
Note
Your LabWindows/CVI process must have superuser privileges to use the function.

UNIX Asynchronous Signal Handling

The following signals have special meaning in LabWindows/CVI:
SIGPOLL (SIGIO) and SIGPIPE—The LabWindows/CVI TCP Library installs
signal handlers for want to install handlers for these signals, you must call the LabWindows/CVI handlers when your handlers are called. If you attempt to set the signal handler to these signals while running in the LabWindows/CVI environment, LabWindows/CVI restores its own handlers.
SIGINT and SIGQUIT—Normally, the operating system generates these two signals
when you type certain keystrokes (<Ctrl-C> and <Ctrl-\>) in the window from which you invoke LabWindows/CVI. If one of these signals occurs while your program is running and you have not installed a handler for it, LabWindows/CVI suspends your program the next time it calls a function that processes events (such as
ProcessSystemEvents). If your program does not call any event-processing
functions, it continues to run.
SIGTERM—LabWindows/CVI treats
SIGQUIT. If this signal occurs while y our pr ogr am is ru nning and yo u ha v e n ot inst alled
a handler for it, LabWindows/CVI terminates the program, gives you a chance to save your files, and exits. If exits immediately.
SIGBUS, SIGFPE, SIGILL, and SIGSEGV—These signals exist to allow for
hardware exceptions. Because execution cannot continue beyond the instruction that caused the exception, LabWindows/CVI always catches these signals. If this signal occurs while your program is running, LabWindows/CVI reports a fatal run-time error
SIGPOLL (SIGIO) and SIGPIPE. If you use the TCP Library and you
SIGTERM as a stronger version of SIGINT and
SIGTERM occurs when no program is running, Lab W indo ws/CVI
plock
SIG_DFL for
©
National Instruments Corporation 5-7 LabWindows/CVI Programmer Reference Manual
Chapter 5 UNIX Compiler/Linker Issues
and suspends operation at the statement that caused the exception. If this signal occurs when no program is running, LabWindows/CVI exits immediately.
You cannot use
signal, sigaction, sigset, or sigvec to make your program ignore the
signals this section lists.
Note If your program begins to loop indefinitely, you can often suspend execution by
sending a signal to the LabWindows/CVI process as follows:
1. Use the
2. Send the LabWindows/CVI process number is 3478, the command sends the execution of your program in LabWindows/CVI, try using If sending the
SIGTERM signal, which terminates not just you r program but also
ps command to identify the process number of LabWindows/CVI.
kill
-SIGNAL pid
SIGINT signal to LabWindows/CVI. When you want to suspend
SIGINT or SIGQUIT signal fails, you must use the stronger
command to that process. For example, if the
kill -INT 3478
SIGINT or SIGQUIT.
LabWindows/CVI.
Note Some signals can cause LabWindows/CVI to dump core you are running a
program that does not install handlers for them.

Solaris 1 ANSI C Library Implementation

The C library that comes with Sun Solaris 1 (SunOS 4.1.x) does not comply with the ANSI C standard as follows:
Some ANSI C functions are missing from the library.
Some library functions have different behavior than the ANSI standard specifies. LabWindows/CVI corrects these problems by linking your programs to a supplemental C
library
libcfix.a, which is in the lib subdirectory of the LabWindows/CVI installation
directory . This library co ntains replacement functions fo r some Sun Solaris functions an d for the ANSI functions that are not available in the Sun Solaris library. The names of the replacement functions differ from the Sun Solaris function names and do not interfere with programs or libraries t hat depend upon the non- ANSI behavior of s ome Sun Solaris functi ons. The LabWindows/CVI ANSI header files contain macro definitions for the replacement functions. When you compile with the LabWindows/CVI headers, your program references the LabWindows/CVI replacement functions instead of the Sun Solaris versions.
Consider the case of Sun Solaris 1 implementation of the
realloc, which LabWindo ws/CVI replaces with _cvi_realloc. The
realloc function fails when the first argument is
NULL. The ANSI standard requires that
libcfix.a, LabWindows/CVI defines _cvi_realloc, which treats a NULL
library argument as the ANSI standard prescribes. The LabWindows/CVI header file
LabWindows/CVI Programmer Reference Manual 5-8
realloc accept NULL as a first argument. In the
stdlib.h
©
National Instruments Corporation
Loading...