═══ About this Information ═══ The How Do I... information provides solutions to common tasks that you would perform with the various components of VisualAge C++. Before you begin to use this information, it would be helpful to understand how to navigate through it:  Use the Contents and Index facilities to locate topics.  Use the Search facility to search the text of this document.  Use hypertext links to acquire related information on the current topic. Hypertext links appear in a different color (which you can customize using the OS/2 Scheme Palette). For example, below there are two lists of hypertext links. By double-clicking on the text of the link or by pressing Enter on a highlighted link, you will open a panel of related information. To shift the focus to other links using the keyboard, use the Tab key. For more information on using this help facility, see:  How to Use the Contents  How to Obtain Additional Information  How to Access and Use IPF Facilities For more information, see:  Other Information You Might Find Helpful  Communicating Your Comments to IBM  Notices  Trademarks ═══ How to Use the Contents ═══ The Contents window is the first to appear. Some topics have a plus ( ) icon beside them. This icon indicates that additional topics are available. To expand the Contents if you are using a mouse, click on the plus ( ) icon. If you are using the keyboard, use the Up or Down Arrow key to highlight the topic, and press the plus (+) key. To see additional topics for a heading with a plus ( ) icon, click on the icon or highlight that topic and press the plus (+) key. To view a topic, double-click on the topic (or press the Up or Down Arrow key to highlight the topic, and then press the Enter key). ═══ How to Obtain Additional Information ═══ After you select a topic, the information for that topic appears in a window. Highlighted words or phrases indicate that additional information is available. Certain words and phrases are highlighted in a different color from the surrounding text. These are called hypertext terms. If you are using a mouse, double-click on the highlighted word. If you are using a keyboard, press the Tab key to move to the highlighted word, and then press the Enter key. Additional information then appears in a window. ═══ How to Access and Use IPF Facilities ═══ Several choices are available for managing the information presented in this document. There are three PullDown menus: the Services menu, the Options menu, and the Help menu. The actions that are selectable from the Services menu operate on the active window currently displayed on the screen. These actions include the following: Placing Bookmarks You can set a placeholder so you can retrieve information of interest to you. Searching for Information You can find occurrences of a word or phrase in the current topic, selected topics, or all topics. Printing Information You can print one or more topics. You can also print a set of topics by first marking the topics in the Contents list. Copying Information to a File You can copy a topic that you are viewing to the System Clipboard or to a file that you can edit. This method is particularly useful for copying syntax definitions and program samples into the application that you are developing. Using the actions that are selectable from the Options menu, you can change the way your Contents list is displayed. To expand the Contents and show all levels for all topics, choose Expand all from the Options PullDown menu. You can also press the Ctrl, Shift and * keys together. The actions that are selectable from the Help menu allow you to select different types of help information. For information about any of the menu choices, highlight the choice in the menu and press F1. ═══ Placing Bookmarks ═══ When you place a bookmark on a topic, it is added to a list of bookmarks you have previously set. You can view the list, and you can remove one or all bookmarks from the list. If you have not set any bookmarks, the list is empty. To set a bookmark, do the following: 1. Select a topic from the Contents. 2. When that topic appears, select the Bookmark option from the Services menu. 3. If you want to change the name used for the bookmark, type the new name in the field. 4. Click on the Place radio button (or press the Up or Down Arrow key to select it). 5. Click on OK (or select it and press Enter). The bookmark is then added to the bookmark list. ═══ Searching for Information ═══ You can specify a word or phrase to be searched. You can also limit the search to a set of topics by first marking the topics in the Contents list. To search for a word or phrase in all topics, do the following: 1. Select the Search option from the Services menu. 2. Type the word or words to be searched for. 3. Click on All sections (or press the Up or Down Arrow keys to select it). 4. Click on Search (or select it and press Enter) to begin the search. 5. The list of topics where the word or phrase appears is displayed. ═══ Printing Information ═══ You can print one or more topics, the index, or the table of contents. Make sure that your printer is connected to the serial port, configured correctly, and ready for input. To print: 1. Select Print from the Services menu. 2. Select what you want to print. Note that the This section and Marked sections choices are only available if you are viewing a topic or if you have marked topics, respectively. To mark topics in the table of contents, press the Ctrl key and click on the topics, or use the arrow keys. 3. Select Print to print what you've chosen on your printer. ═══ Copying Information to a File ═══ You can copy a topic that you are viewing in two ways:  Copy copies the topic that you are viewing into the System Clipboard. If you are using a Presentation Manager (PM) editor (for example, the Enhanced Editor) that copies or cuts (or both) to the System Clipboard, and pastes to the System Clipboard, you can easily add the copied information to your program source module.  Copy to file copies the topic that you are viewing into a temporary file named TEXT.TMP. You can later edit that file by using any editor. TEXT.TMP is placed in the directory where your viewable document resides. To copy a topic, do the following: 1. Expand the Contents list and select a topic. 2. When the topic appears, select Copy to file from the Services menu. 3. The system puts the text pertaining to that topic into the temporary file TEXT.TMP. ═══ Other Information You Might Find Helpful ═══ The VisualAge C++ provides a number of online guides and references that we hope you'll find helpful as you develop applications. This information includes:  User's Guide information provides conceptual and usage information,  Reference information is organized for quick access, and  How Do I... information gives you specific instructions for performing common tasks. You can get to this online information from the Information folder inside the main product folder. You can also get to it from the Help menu in any of the components of the product. ═══ Communicating Your Comments to IBM ═══ If there is something you like, or dislike, about this document, please let us know. You can use one of the methods listed below to send your comments to IBM. Please be sure to include the complete title of the publication that you are commenting on. For example, you would refer to the How Do I... information for the Browser as: VisualAge C++ Browser: How Do I... for OS/2. The comments you send should only pertain to the information in this document and its presentation. To request additional publications or to ask questions or make comments about the functions of IBM products or systems, you should talk to your IBM representative or your authorized IBM remarketer. When you send comments to IBM, you grant IBM a nonexclusive right to use or distribute your comments in any way it believes appropriate without incurring any obligation to you. You can send your comments to IBM in the following ways:  By mail to the following address: IBM Canada Ltd. Laboratory Information Development 2G/345/1150/TOR 1150 EGLINTON AVENUE EAST NORTH YORK, ONTARIO CANADA M3C 1H7  By FAX to the following number: - United States and Canada: (416) 448-6161 - Other countries (+1) 416-448-6161  By electronic mail to one of the following IDs. Be sure to include your entire network address if you wish to get a reply. - Internet: torrcf@vnet.ibm.com - IBMLink: toribm(torrcf) - IBM/PROFS: torolab4(torrcf) - IBMMAIL: ibmmail(caibmwt9 ═══ Notices ═══ Copyright International Business Machines Corporation, 1995. All rights reserved. Note to U.S. Government Users - Documentation related to restricted rights - Use, duplication, or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp. This edition applies to Version 3.0 of IBM VisualAge C++ for OS/2 (30H1664, 30H1665, 30H1666) and to all subsequent releases and modifications until otherwise indicated in new editions. Make sure you are using the correct edition for the level of the product. This publication could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; any such changes will be reported in subsequent revisions. Requests for publications and for technical information about IBM products should be made to your IBM Authorized Dealer or your IBM Marketing Representative. When you send information to IBM, you grant IBM a nonexclusive right to use or distribute the information in any ways it believes appropriate without incurring any obligation to you. Any reference to an IBM licensed program in this publication is not intended to state or imply that only IBM's licensed program may be used. Any functionally equivalent product, program, or service that does not infringe any of IBM's intellectual property rights may be used instead of the IBM product, program, or service. Evaluation and verification of operation in conjunction with other products, except those expressly designated by IBM, is the user's responsibility. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing. IBM Corporation, 500 Columbus Avenue, Thornwood, NY, 10594, USA. This publication contains examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples include the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental. ═══ Trademarks and Service Marks ═══ The following terms used in this publication are trademarks or service marks of IBM Corporation in the United States or other countries: C/2 C Set/2 C Set ++ Common User Access CUA IBM Operating System/2 OS/2 Personal System/2 Presentation Manager PS/2 VisualAge WorkFrame/2 Other company, product, and service names, which may be denoted by a double asterisk(**), may be trademarks or service marks of others. ═══ 1. Access Help ═══ You can access the VisualAge C++ documentation in two ways:  Use the Help PullDown menu from any VisualAge C++ component, and select the VisualAge C++ Documentation Cascade menu, or  Open the Information folder within the VisualAge C++ desktop folder and double-click on the information icon of your choice. For a list of online information available for the VisualAge C++ product, select the ? PushButton on the How Do I... information ButtonBar below. Related Tasks  How do I get support ═══ 2. Access VisualAge C++ Components ═══ You can access all components in three ways:  Double-click on the component's icon located in the Tools folder of the VisualAge C++ desktop folder.  From the command line. (Double-click on a component listed below for syntax).  If you have a WorkFrame project, from the Project PullDown menu on any component, or from the WorkFrame project icon PopUp menu. Select one of the tools below for more information:  Browser  Data Access Builder  Debugger  Editor  Performance Analyzer  Visual Builder  WorkFrame ═══ 3. Add/Delete VisualAge C++ Components ═══ Once VisualAge C++ has been installed, you can go back to the install program to install additional components or reinstall components that you have changed or erased. You can also use the install program to remove VisualAge C++ components or backup versions of components from your workstation. 1. Open the Tools folder located in the VisualAge C++ desktop folder. 2. Double-click on the Installation Utility icon. The VisualAge C++ Installation and Instruction windows appear. 3. Select the Continue PushButton in the Instruction window. The Installation Options window appears showing three options (double-click on an option below for more information):  Update the currently installed components  Delete the installed components and re-install  Install additional components For more details, see the Read Me First booklet. ═══ Updating the currently installed components ═══ Use this procedure to overwrite all currently installed components with the installation files. Warning: This option updates everything you have installed; you cannot choose individual components to update. 1. Choose Update the currently installed components and select the Continue PushButton. The Update window appears. 2. Choose whether you want to have your config.sys automatically updated and whether you want to save a backup version of this installation in case you ever need to restore it. 3. Select the Update PushButton. 4. Select the Yes PushButton on any information dialogs that may appear. 5. A Progress window shows the status of the update process. When all the components files and related information have been updated, a message box appears. Select the OK PushButton. 6. Select the Exit PushButton from the VisualAge C++ Installation window. ═══ Deleting the installed components and re-install ═══ Use this procedure to delete the installed components, including their desktop objects and any entries in any .INI files. You can then reinstall them if you like. 1. Choose Delete the installed components and re-install and select the Continue PushButton. 2. Select the components that you want to delete. Use the Select All PushButton to choose all components. 3. Select the Delete PushButton. 4. A Progress window shows the status of the deletion process. When all selected components have been deleted, a message box appears. Select the OK PushButton. 5. Select the Exit PushButton from the VisualAge C++ Installation window. ═══ Installing additional components ═══ Use this procedure to install components that are not already installed. 1. Choose Install additional components and select the Continue PushButton. The Installation window appears. 2. Choose whether you want to have your config.sys automatically updated and whether to overwrite existing files. 3. Select the OK PushButton. The Install - directories window appears listing only the components that you have not yet installed. 4. Select the components that you want to install. 5. Select the Install PushButton. 6. A Progress window shows the status of the installation process. When all selected components have been installed, a message box appears. Select the OK PushButton. 7. Select the Exit PushButton from the VisualAge C++ Installation window. 8. Reboot your system to make the changes to the config.sys file take effect. Note that if you did not have your config.sys file automatically updated, then first make the appropriate changes based on the config.add file that was created by the installation process. Also, if you chose to install WorkFrame, a second phase of installation will begin when you reboot. This can be run in the background by selecting the Hide PushButton from the second phase installation window. ═══ 4. Analyze Performance ═══ The Performance Analyzer is an OS/2 based application that helps you improve and understand the behavior of IBM C/C++ applications. The Performance Analyzer traces the execution of your application and creates a trace file. The trace file contains trace analysis data that can be displayed in diagrams. Using these diagrams, you can improve the performance of an application, determine what led to certain faults, and in general, understand what happens when your application runs. The Performance Analyzer does not replace static analyzers or debuggers, but it can complement them by helping you understand aspects of the application that would otherwise be difficult or impossible to see. To start the Performance Analyzer:  Double-click on the Performance Analyzer icon found in the Tools folder which is located in the VisualAge C++ desktop folder.  From the WorkFrame project environment, select Analyze from the WorkFrame PullDown menu.  If you use a WorkFrame project to access another component of VisualAge C++, then select Analyze from the Project PullDown menu. Related Information:  The Performance Analyzer How Do I... information  The Performance Analyzer section of the User's Guide ═══ 5. Browse my Files ═══ The Browser lets you look at your source files in many different ways:  List program objects by type, content or component  Graph relationships between program objects  Load the target of a project without recompiling  View and edit the source code  View online documentation for a class or a class member. You can start the Browser from several places:  The OS/2 Command Prompt  The OS/2 Workplace Shell  The WorkFrame environment  The Debugger or Editor Related Tasks:  How do I compile for browsing  How do I link for browsing Related Information:  The Browser How Do I... information  The Browser section of the User's Guide ═══ Starting the Browser from the OS/2 Command Prompt ═══ To start the Browser from the command line, type: icsbrs [file_name] Where file_name can be a Browser database file (with extension .PDB, .PDD, .PDE, .PDL) or a program file that has been linked with the /BROWSE option (with extension .DLL, .EXE, .LIB). Note that you can also load multiple .PDB file names and merge multiple file types. See the User's Guide section on Merging Files into the Browser. If you type icsbrs without a file name, you can use the Load Cascade menu on the File PullDown menu from the Browser user interface to load files. Related Information:  The Browser How Do I... ═══ Starting the Browser from the OS/2 Workplace Shell ═══ You can start the Browser from the OS/2 Workplace Shell in three ways:  Double-click on the Browser icon in the VisualAge C++ desktop folder.  Double-click on a Browser database file (.PDB, .PDD, .PDE, or .PDL) from a Workplace Shell or WorkFrame folder.  Drag a Browser database file or program file linked with the /BROWSE option (.DLL, .EXE, or .LIB) or WorkFrame project icon onto the Browser icon. Related Information:  The Browser How Do I... ═══ Starting the Browser from the WorkFrame environment ═══ To start the Browser from the WorkFrame environment, you can:  Double-click on a Browser database object (.PDB, .PDD, .PDE or .PDL) in any WorkFrame project folder,  Select Browse from any WorkFrame project System menu to load a Browser session, or  Select the Browse action from the PopUp on any Browser database object. Related Information:  The Browser How Do I... ═══ Starting the Browser from the Debugger or Editor ═══ To start the Browser from the Debugger: 1. Select the Project PullDown menu from the Debugger user interface. 2. Select the Browse Cascade menu. 3. Select a Browser action to perform on the program currently loaded into the Debugger or on a selected program element. To start the Browser from the Editor: 1. Select the Browser PullDown menu from the Editor user interface. 2. Select an action to perform on the file currently loaded or on a selected program element. Related Information:  The Browser How Do I... ═══ 6. Change my config.sys File for VisualAge C++ ═══ If you chose not to have the installation program automatically update your config.sys file, you must make changes to the environment variables it contains before you can use VisualAge C++. If you are installing WorkFrame, you must make these changes before the second phase of installation can begin. (The second phase starts after you reboot your system). To make it easier for you, the install program creates a file called config.add, which contains the changes you will need to make. You can find config.add in the target install directory. Note: The CSETENV.CMD file in the BIN directory also contains the environment settings for VisualAge C++. You can run this command file before using VisualAge C++ in order to set the proper environment variables. Note that these changes will only be valid for the current OS/2 session. ═══ 7. Code in C and C++ ═══ The following are some topics on coding in C and C++:  Using & and * on pointers and arrays  Handling exceptions  Demangling (decode) a C++ function name  Changing locale without recompiling  Redirecting standard input/output streams  Mixing old and new templates  Creating a multithread program For more information on coding in C and C++, see:  The Coding Your Program section of the Programming Guide, or  The Language Reference ═══ 7.1. Using & and * on pointers and arrays ═══ Use the address operator (&) to return a pointer to the location of the operand. Use the indirection operator (*) to access the data object that is pointed to. For example, the following lines define pSample as a pointer to type int and a as an int: int *pSample; int a; and the following statements together assign the value 3 to a: pSample = &a; /* pSample points to variable a */ *pSample = 3; /* whatever pSample points to gets value 3 */ Related Information:  The Unary Expressions section of the Language Reference ═══ 7.2. Handling exceptions ═══ The VisualAge C++ product and the OS/2 operating system both have the capability to detect and report runtime errors and abnormal conditions. Abnormal conditions can be reported to you and handled in one of the following ways:  Using VisualAge C++ signal handlers. Signals are a mechanism by which a process (thread) may be notified of, or affected by, an event occurring in the system. Error handling by signals can be used in both C and C++ programs.  Using OS/2 exception handlers. Exceptions are any system, logic, or user error detected by a function that does not itself deal with the error but passes the error on to an exception handling routine. The VisualAge C++ library provides a C-language OS/2 exception handler, _Exception, to map OS/2 exceptions to C signals and signal handlers. You can also create and use your own exception handlers. OS/2 exceptions and exception handlers are described in the Control Program Guide and Reference documentation.  Using C++ exception handling constructs. These constructs belong to the C++ language definition and can only be used in C++ code. Both signal and OS/2 exception handling are implemented in C++ as they are in C. Note: You should use the Debugger to debug exception handling problems, since complete notification and stack tracing are available through the Debugger. The following topics are covered in this section:  Common problems that generate exception  Handling OS/2 exceptions  Creating your own OS/2 exception handlers  Handling C++ exceptions  Handling C/C++ signals  Handling signals and OS/2 exceptions in DLLs  OS/2 exceptions handling considerations  Handling signals in a multithread program Related Information:  The C++ Exception Handling section of the Language Reference  The Signal and OS/2 Exception Handling section of the Programming Guide ═══ 7.2.1. Common problems that generate exceptions ═══ The following is a list of some of the common problems that can generate runtime exceptions:  Improper use of memory. For example, using a pointer to an object that has already been freed can cause an exception, as can corrupting the heap.  Using an invalid pointer.  Passing an invalid parameter to a system function.  Return codes from library or system calls that are not checked. ═══ 7.2.2. Handling OS/2 exceptions ═══ An OS/2 exception is generated by the operating system to report an abnormal condition. OS/2 exceptions are grouped into two categories: Asynchronous exceptions Which are caused by actions outside of your current thread. There are only two:  XCPT_SIGNAL, caused by a keyboard signal (Ctrl-C or Ctrl-Break) or the process termination exception. This exception can only occur on thread 1 of your process.  XCPT_ASYNC_PROCESS_TERMINATE, caused by one of your threads terminating the entire process. This exception can occur on any thread. Synchronous exceptions Which are caused by code in the thread that receives the exception. All other OS/2 exceptions fall into this category. Just as you use signal handlers to handle signals, use exception handlers to handle OS/2 exceptions. Exception handling offers additional function, but signal handling is simpler, so you may want to use both. Related Information:  Default OS/2 Exception Handling  The Handling OS/2 Exceptions in the Programming Guide ═══ VisualAge C++ default OS/2 exception handling ═══ The VisualAge C++ library provides its own default exception handling functions:  _Lib_excpt, for OS/2 exceptions occurring in library functions, and  _Exception, for all other OS/2 exceptions. You can use these exception handlers or create and register your own. ═══ 7.2.3. Creating your own OS/2 exception handler ═══ You can use OS/2 APIs and the information provided in the bsexcpt.h header file found in the \IBMCPP\INCLUDE\OS2 directory to create your own exception handlers to use alone or with the two provided handler functions. Exception handlers can be complex to write and difficult to debug, but creating your own offers you two advantages: 1. You receive more information about the error condition. 2. You can intercept any OS/2 exception. The VisualAge C++ library passes some exceptions back to the operating system because there is no C semantic for handling them. Related Information:  The Creating your own OS/2 Exception Handler section of the Programming Guide ═══ 7.2.4. Handling C++ exceptions ═══ C++ provides three language constructs to implement exception handling:  try and catch blocks, syntax: try { statement [statement] } catch ( type-specifier [type-specifier] [declarator | abstract-declarator ] { statement [statement] }  throw expressions, syntax: throw [assignment-expression] The steps required to implement an exception handler are: 1. Functions that are expected to be used by many programs are coded so that, when an error is detected, an exception is thrown. The throw expression generally throws an object. It may be created explicitly for purposes of exception handling, or it may be the object that caused the error to be detected. 2. Exceptions are anticipated in a caller by means of a try statement. Function calls that you anticipate might produce an exception must be enclosed in braces and preceded by the keyword try. 3. Immediately following the try block, you must code one or more catch blocks. Each catch block identifies what type or class of objects it can catch: a. If the object thrown matches the type of a catch expression, control passes to that catch block. b. If the object thrown does not match the first catch block, subsequent catch blocks are searched for a matching type. c. If no match is found, the search continues in all enclosing try blocks and then in the code that called the current function. d. If no match is found after all try blocks are searched, a call to terminate() is made. Notes on throwing exceptions:  Any object can be thrown if it can be copied and destroyed in the function from which the throw occurs.  Exceptions should never be thrown from a C language signal handler. The result is undefined, and can cause program termination. Related Information:  The C++ Exception Handling section of the Language Reference ═══ 7.2.5. Handling C/C++ signals ═══ Signals are C and C++ language constructs provided for error handling. A signal is a condition reported as a result of an error in program execution. It may also be caused by deliberate programmer action. With the VisualAge C++ product, operating system exceptions are mapped to signals for you. The VisualAge C++ product provides a number of different symbols to differentiate between error conditions. The signal constants are defined in the signal.h header file. C provides two functions that deal with signal handling in the runtime environment: raise and signal. Signals can be reported by an explicit call to raise, but are generally reported as a result of:  A machine interrupt (for example, division by zero),  A user action (for example, pressing Ctrl-C or Ctrl-Break), or  An operating system exception. Use the signal function to specify how to handle a particular signal. For each signal, you can specify one of 3 types of handlers: SIG_DFL Use the VisualAge C++ default handling. For most signals, the default action is to terminate the process with an error message. SIG_IGN Ignore the condition and continue running the program. Some signals cannot be ignored, such as division by zero. If you specify SIG_IGN for one of these signals, the VisualAge C++ library will treat the signal as if SIG_DFL was specified. Your own signal handler function Call the function you specify. It can be any function, and can call any library function. Note that when the signal is reported and your function is called, signal handling is reset to SIG_DFL to prevent recursion should the same signal be reported from your function. The initial setting for all signals is SIG_DFL, the default action. Related Information:  Default Handling of Signals  The raise - Send Signal section of the C Library Reference  The signal - Handle Interrupt Signals section of the C Library Reference ═══ Default handling of signals ═══ The runtime environment will perform default handling of a given signal unless a specific signal handler is established or the signal is disabled (set to SIG_IGN). You can also set or reset default handling by coding: signal(sig, SIG_DFL); The default handling depends upon the signal that is being handled. For most signals, the default is to pass the signal to the next exception handler in the chain. Unless you have set up your own exception handler, the default OS/2 exception handler receives the signal and performs the default action, which is to terminate the program and return an exit code. The exit code indicates: 1. The reason for the program termination. 2. The return code from DosExit. When you use signal handlers, keep the following points in mind:  When you call the raise function in a multithread program, the handler for the signal you raise must be established on the thread where the call was made.  If your signal handler resides in a dynamic link library (DLL), ensure that you change the signal handler when you unload the DLL. If you unload your DLL without changing the signal handler, no warnings or error messages are generated. When your signal handler gets called, your program will probably terminate. If another DLL has been loaded in the same address range, your program may continue but with undefined results.  Variables referenced by both the signal handler and by other code should be given the attribute volatile. Declaring the variables as volatile indicates to the compiler that references to these variables may have side effects, so the compiler stores changes to the variables immediately. ═══ 7.2.6. Handling signals and OS/2 exceptions in DLLs ═══ ═══ 7.2.7. OS/2 exception handling considerations ═══ All the restrictions for signal handling apply to exception handling as well. There are also a number of additional considerations you should keep in mind when you use exception handling:  You must register an exception handler whenever you change library environments to ensure that exception handling is provided for all C code.  Ensure that you always deregister your exception handler.  If you register your own exception handler, the OS/2 exceptions you handle are not seen by a signal handler. The exceptions you do not handle are passed to the next exception handler.  If you are using OS/2 semaphores and an exception occurs while your code owns a semaphore, you must ensure that the semaphore is released.  Always check the exception flags to determine how the exception occurred.  Keep your exception handler simple and specific.  Check for and handle only the exceptions that you expect to encounter, and provide a default exception handler to handle unexpected exceptions.  You need approximately 1.5K of stack remaining for the operating system to be able to call your exception handler.  Neither of the VisualAge C++ default exception handlers are available in the subsystem libraries. Related Information:  The Handling OS/2 Exceptions ═══ 7.2.8. Handling signals in a multithread program ═══ The default handling of signals is usually either to terminate the program or to ignore the signal. However, special-purpose signal handling can be complicated in the multithread environment. Signal handlers are registered independently on each thread. For example, if thread 1 calls signal as follows: signal (SIGFPE, handlerfunc); then the handler handlerfunc is registered for thread 1 only. Any other threads are handled using the defaults. A signal is always handled on the thread that generated it, except for SIGBREAK, SIGINT, and SIGTERM. These three signals are handled on the thread that generated them only if they were raised using the raise function. If they were raised by an exception, they will be handled on thread 1. Related Tasks:  How do I create a multithread program  How do I compile and link a multithread program Related Information:  The Signal Handling in Multithread Programs section of the Programming Guide ═══ 7.3. Demangling (decoding) a C++ function name ═══ When the VisualAge C++ compiler compiles a C++ program, it encodes all C++ symbolic names to include type and scoping information. This is called mangling. The linker uses the mangled names in the object files to resolve external references using the exported names. Exported names are functions and certain other identifiers that are made available to programs that call the dynamic link library (DLL) in which the names are defined. Tools that use the files with mangled names do not have access to the original source, and therefore present the mangled names. Use the CPPFILT utility to convert mangled names to demangled names in two separate modes: text and binary. All output is sent to stdout. To demangle a text file: cppfilt text_file_name To demangle a binary .OBJ and .LIB file: cppfilt /B obj_file_name lib_file_name Note: You can use options on the CPPFILT utility. Use the /? for a list of possible options available. Related Information:  The Demangling Compiled C++ Names with CPPFILT section of the User's Guide ═══ 7.4. Changing locale without recompiling my code ═══ You can use environment variables to specify the names of locale categories. You must call setlocale regardless of environmental variable settings. However, if you do not explicitly specify the name, the locale is changed according to the environment variables. For example, the following causes the environment variable LC_ALL to be initialized to the value TEXAN: _putenv("LC_ALL=TEXAN"); To change a locale from within your code: 1. Be sure to include the locale header file: #include 2. Use the following lines to set the locale: setlocale(LC_ALL, ""); _putenv("LC_ALL=TEXAN"); The names of the environment variables match the names of the locale categories: LC_ALL LC_COLLATE Defines the relative order between collating elements (characters and multicharacter collating elements) in the locale. LC_CTYPE Defines character classification, case convention, and other character attributes. LC_MESSAGES Defines the format and values for positive and negative responses. LC_MONETARY Defines the rules and symbols used to format monetary quantities. LC_NUMERIC Defines the rules and symbols used to format non-monetary numeric information. LC_TIME Defines the interpretation of the field description used for passing, then formatting, the data. LC_TOD Defines the rules to define the beginning, end, and duration of daylight savings time, and the difference between local time and Greenwich Mean Time. LC_SYNTAX Defines the variant characters from the portable character set. Related Information:  The Introduction to Locale section of the Programming Guide  The Locale Categories section of the Programming Guide ═══ 7.5. Redirecting standard input/output streams ═══ There may be times when you want to redirect a standard stream to a file. There are two ways to do this:  From within a program  From the command line ═══ 7.5.1. Redirection from within a program ═══ To redirect C standard streams to a file from within your program, use the freopen library function. For example, to redirect your output to a file called pia.out instead of stdout, code the following statement in your program: freopen("pia.out", "w", stdout); You can reassign a C++ standard stream to another istream (cin only) or ostream object, or to a streambuf object, using the operator=. For example, to redirect your output to a file called sample.out, create sample.out as an ostream object, and assign cout to it: #include int main(void) { cout << "This is going to the standard output stream" << endl; ofstream outfile("sample.out"); cout = outfile; cout << "This is going to sample.out file" << endl; return 0; } You could also assign cout to outfile.rdbuf() to perform the same redirection. Related Information:  The Associating a File with a Standard Input or Output Stream section of the Open Class Library User's Guide ═══ 7.5.2. Redirection from the command line ═══ To redirect a C or C++ standard stream to a file from the command line, use the standard OS/2 redirection symbols. For example, to run the program sample.exe, which has two required parameters XYZ and 123, and redirect the output from stdout to a file called sample.out, you would use the following command: bill XYZ 123 > bill.out You can also use the OS/2 file handles to redirect one standard stream to another. For example, to redirect stderr to stdout, you would use the 2> redirection symbol: bill XYZ 123 2> bill.err Note: You cannot use redirection from the command line for memory files. Related Information:  Refer to the OS/2 online Master Help Index for more information on redirection symbols. ═══ 7.6. Mixing old and new templates ═══ The way that VisualAge C++ resolves template functions and data is new for this release. Suppose that you are linking a new application, and you want to link object files or static libraries that:  Were created using a previous release of VisualAge C++.  Contain templates. To perform such a link, you must compile with the /Gk+ option. When you specify this option, ICC uses the template resolution method from previous releases. In addition, this option causes the compiler to supply the /OLDCPP option to the linker. If you do not specify the /Gk+ option, the linker produces an error message asking you to link using /OLDCPP. If you get this error message, you should recompile using the /Gk+ option. Related Information:  The Using Templates section of the Programming Guide ═══ 7.7. Creating a multithread program ═══ A multithread program is one whose functions are divided among several threads. A process is an executing application and the resources it uses, a thread is the smallest unit of execution within a process. Other than its stack and registers, a thread owns no resources; it uses those of its parent process. Multithread programming is a feature of the OS/2 operating system and is supported by the VisualAge C++ compiler with: Multithread libraries The VisualAge C++ compiler has two standard libraries that provide library functions for use in multithread programs. The CPPOM30.LIB library is a statically linked multithread library, and CPPOM30I.LIB is an import multithread library, with the addresses of the functions contained in the VisualAge C++ DLLs. In addition, the follow classes of the VisualAge C++ Open Class Library are available in multithread form:  The User Interface classes,  The Complex Mathematics classes, and  The I/O Stream classes. Note that when you use the multithread libraries, you have more to consider than with the single-thread libraries. For example, access to resources must be limited to one thread at a time to prevent functions from interfering with each other, other functions can affect all threads running within a process, and global variables and error handling are also affected by the multithread environment. Code generation and linking options When you compile your multithread program, you must specify that you want to use the multithread libraries. Because threads share data, the operating system and library functions must ensure that only one thread is reading or writing data at a time. The multithread libraries provide this support. To indicate that you want the multithread libraries, specify the /Gm+ compiler option. You must compile all modules with this option. You cannot mix multithread with singlethread. You can use either static (/Gd-) or dynamic (/Gd+) linking with multithread programs. Related Tasks:  How do I compile and link a multithread program  How do I handle signals in a multithread program Related Information:  The Creating Multithread Programs section of the Programming Guide ═══ 8. Combine C and C++ ═══ The following are some topics on combining the C and C++ language conventions. Note that this is not an exhaustive list:  Calling a C++ function from a C program  Using C Objects in C++ programs  Creating header files to work with both C and C++  Handling C/C++ signals  Migrating headers from 16-bit to 32-bit C or C++ For more information on combining C and C++, see:  The Coding Your Program section of the Programming Guide, or  The Language Reference ═══ 8.1. Calling a C++ function from a C program ═══ To call a C++ routine defined in a .CPP file from a C file: 1. Define the C++ function as extern "C" in your C++ code. 2. Call the function from the C code. ═══ 8.2. Using C objects in C++ programs ═══ To link your C++ code with C objects:  You must inform the C++ compiler that an external name uses C naming conventions, by using the extern "C" when you declare the function. If you do not use this convention, the C++ compiler mangles the name. Note: Using the keywords for calling conventions, such as _System and _Optlink, in your function definition is equivalent to defining the function as extern "C". ═══ 8.3. Creating header files to work with both C and C++ ═══ ═══ 8.4. Handling C/C++ signals ═══ ═══ 8.5. Migrating headers from 16-bit to 32-bit C or C++ ═══ ═══ 9. Compile and Link a Multithread Program ═══ When you compile a multithread program, you must specify that you want to use the multithread libraries. Because threads share data, the operating system and library functions must ensure that only one thread is reading or writing data at one time. The multithread libraries shipped with VisualAge C++ provide this support. To indicate that you want the multithread libraries, specify the /Gm+ compiler option. Conversely, the /Gm- option, which is the default, specifies the use of the single-thread version of the library. If you intend to compile your source code into separate modules and then link them into one executable program file, you must compile each module using the /Gm+ option and ensure that the multithread libraries are used when you link them. You cannot mix modules that have been compiled with /Gm+ with modules compiled using /Gm-. You can use either static (/Gd-) or dynamic (/Gd+) linking with multithread programs. Related Tasks:  How do I create a multithread program  How do I handle signals in a multithread program Related Information:  The Creating Multithread Programs section of the Programming Guide ═══ 10. Compile my Programs ═══ You can compile your programs in three ways. Note that this is not an exhaustive list:  From within WorkFrame  From the command line  Using a make file The output created from compiling the source can be:  An .EXE file  An .OBJ file  A PM program  SOM Code You can also compile your source to generate information for:  Debugging  Browsing  Analysis You can use the compiler options to:  Control messages  Control #include Search Paths  Create a compiler listing  Optimize for speed and size  Set the source code language level  Set the calling convention  Set the stack size Related Tasks:  How do I compile and link a multithread program  How do I set compiler options using WorkFrame Related Information:  The Compiling section of the User's Guide ═══ 10.1. Compiling from within WorkFrame ═══ To compile the target of a WorkFrame project:  From the project icon: 1. Click Mouse Button 2 on the WorkFrame project icon. 2. Select the Build menu item.  Or, from within the project environment: 1. Select the Project PullDown menu. 2. Select the Build menu item. WorkFrame will build the project's target based on the compiler options set. To compile individual files or groups of files from within the WorkFrame project environment: 1. Double-click on the WorkFrame project icon to open the project environment. 2. Select the source files that you want to compile. 3. Click Mouse Button 2 on the background, or select the Selected PullDown menu. 4. Select the Compile menu item. Related Tasks:  How do I develop using WorkFrame  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line Related Information:  The WorkFrame How Do I information  The WorkFrame section of the User's Guide ═══ 10.2. Compiling from the command line ═══ Depending on how you want to compile your files and how you have set up the ICC environment variable, many of the parameters used with the icc command are optional when you issue the command from a command line. The syntax for the icc command is as follows: icc [@response_file] or icc [/options source_file | intermediate_file | object | library | def_file ] For example, to compile and link the program bob.c, you would enter the following: icc bob.c An object code file bob.obj, and an executable file bob.exe are created. Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from within WorkFrame Related Information:  The Compiler Options section of the User's Guide ═══ Compiling using response files ═══ Instead of specifying compiler options and source files on the command line, you can use a response file. A response file is a text file that contains a string of options and file names to be passed to icc. (The string does not specify icc itself.) For example, the response file that contains the following: /Sa /Fl sample.c would give the following command line: icc /Sa /Fl sample.c A response file can have any valid file name and extension. To use the response file, specify it on the icc command line preceded by the at sign (@). For example: icc @d:\response.fil No space can appear between the @ and the file name. You can use multiple response files, and even call another response file from within a response file. You can mix response files with other input on the command line. Options and file names set in the ICC environment variable are still used. The command string in a response file can span multiple lines. No continuation character is required. The string can also be longer than the limit imposed by the OS/2 command line. In some situations you may need to use a response file to accommodate a long command line, such as when you use the intermediate code linker or compile C++ code containing templates. ═══ 10.3. Compiling using a make file ═══ Use a make file to organize the sequence of actions (such as compiling and linking) required to build your project. You can then invoke all the actions in one step. The NMAKE utility can save you time by performing actions on only the files that have changed, and on the files that incorporate or depend on the changed files. You can write the make file yourself, or you can use the WorkFrame tool MakeMake to write it for you. Related Tasks:  How do I create make files and dependency files ═══ 10.4. Compiling to an .EXE file ═══ By default, the compiler generates one executable file for each compiler invocation. If you specify /C+, the compiler generates only object files, which you can then link separately to create an executable file. You can use several compiler options to change the executable file created by the compiler into a:  Dynamically linked runtime library  Statically linked runtime library  Single-thread program  Multithread program  Subsystem See the Code Generation Options section of the User's Guide for more information on changing an .EXE file. Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame ═══ 10.5. Compiling to an .OBJ file ═══ To create object (.OBJ) files, which you can link separately to create an .EXE file:  Compile with the /C+ option. Related Tasks:  How do I create an .EXE file  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame Related Information:  The Code Generation Options section of the User's Guide ═══ 10.6. Compiling to a PM program ═══ If you are using the VisualAge C++ product to develop PM applications, you may need the following options: Option Description /Se Allow all VisualAge C++ language extensions. (This is the default.) /Gm Use the multithread libraries. /Gs- Do not remove stack probes. (This is the default.) /Wpro Produce diagnostic messages about unprototyped functions. (These are generated by default). Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame ═══ 10.7. Compiling to SOM code ═══ To compile your source for SOM choose from the following options: /Fr Use this option to have the compiler write the release order of the specified class to standard output. The release order is written in the form of a SOMReleaseOrder pragma. You can capture the output from this option when developing new SOM classes, and include the pragma in the class definition. /Fs[+|-|filename|directory] Use this option to have the compiler generate an IDL file when a file with an .h extension is explicitly specified on the command line. /Ga[+|-] Turns on implicit SOM mode, and also causes the file som.hh to be included. It is equivalent to placing #pragma SOMAsDefault(on) at the start of the translation unit. /Gb[+|-] Instructs the compiler to disable direct access to attributes. Instead, the get and set methods are used. It is equivalent to placing #pragma SOMNoDataDirect(on) as the first line of the translation unit. /Gz[+|-] Causes the initialization of the SOM classes to be done during static initialization time. If this option is set on, code is generated to check if the class has already been initialized. With either setting of this option, any reference to a static member of a SOM class will cause the class to be initialized. The default setting for this option is off. /Xs Excludes files in the specified directories when implicit SOM mode is turned on (when classes are implicitly derived from SOM). Note: SOM options that affect the same settings as SOM pragmas are effective except when overriden by those pragmas. Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame Related Information:  The IBM System Object Model section of the Programming Guide ═══ 10.8. Compiling for debugging ═══ The information necessary for running the VisualAge C++ Debugger can be placed in the object file produced by the compiler using the /Ti+ option. If you use icc to automatically invoke the linker and specify the /Ti+ compiler option, the /DE linker option is automatically passed to the linker. The /DE linker option includes the Debugger information in the executable or DLL file. When you use /Ti+, do not turn on optimization (/O+, /Oc+, /Oi+, or /Os+), unless you are using the information with Performance Analyzer, and not with the Debugger. Because the compiler produces debugging information as if the code were not optimized, the information may not accurately describe an optimized program being debugged, which makes debugging difficult. Accurate symbol and type information is not always available. Because of the effects of optimization, debugging information generated with optimization is limited to setting breakpoints at function entry and function exit and stepping through the program at assembly level. Accurate symbol and type information is not always available. If you cannot avoid debugging an optimized program, turn the scheduler off (/Os-), and step through the program at the assembly level, using the Register and Storage windows for information. To make full use of the VisualAge C++ Debugger, set optimization off and use the /G3 option. Note that these are the defaults. Related Tasks:  How do I debug my programs  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame Related Information:  The Debugging section of the User's Guide  The Debugger How Do I... information ═══ 10.9. Compiling for browsing ═══ Use /Fb to produce a browser (.PDB) file. Only compile with /Fb* if the compiler issues a message telling you that you should use it. Note: These options are valid for C++ files only. By default, the compiler does not produce a Browser file. The difference between the two options related to how much Browser information is generated from system include files. That is, those included via: #include as opposed to: #include "local_file.h. The /Fb option discards much of the non-type information from inside of system include files. For instance:  Non-member function declarations will not be included in the .PDB file, including those C and OS/2 header files. Any friendship granted to these types of omitted functions will not be recorded for a class. For instance: // in int foobar(void); // in "bar.h" class bar { friend int foobar(void); } This friendship will not be included in the list of friends of class bar.  No global variable declared, or defined, in the system header file will be included in the .PDB file. This includes variables of an instanstiated template type.  Class member function declarations will be added to the .PDB file, but their inline definitions, if any, will not.  Non-inline function definitions will not be added to the .PDB file. These restrictions are lifted when compiling with the /Fb* option. You should use the /Fb option, unless the compiler issues a message indicating that the use of the /Fb* option is appropriate. Related Tasks:  How do I browse my files  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame Related Information:  The Browser section of the User's Guide  The Browser How Do I... information ═══ 10.10. Compiling for analysis ═══ To include the information required by the Performance Analyzer in the object file, use both the /Ti+ and /Gh+ options. To include the Performance Analyzer information in the executable file or DLL, use the /DE linker option. If you use icc to invoke the linker and specify /Ti+, the /DE option is automatically passed to the linker. When you specify /Gh+, the compiler generates a call to a profiling hook function as the first instruction in the prolog of each function. There are two profiling hook functions: _ProfileHook32 Profile hook for all 32-bit functions. _ProfileHook16 Profile hook for all 16-bit callback functions. These functions are defined with either the _Far16 _Cdecl or _Far16 _Pascal linkage keywords. Related Tasks:  How do I analyze performance  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame Related Information:  The Analyzing Performance section of the User's Guide  The Performance Analyzer How Do I... information ═══ 10.11. Controlling messages ═══ You can use compiler options to control:  The level of error message that the compiler outputs and that increments the error count maintained by the compiler (with the /Wn option).  How many errors are allowed before the compiler stops compiling (with the /Nn option).  The diagnostics run against the code, and the types of messages produced (with the /Wgrp option). Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame ═══ 10.12. Controlling #include search paths ═══ You can control the paths searched by the compiler when it looks for #include files. The paths that are searched are the result of the information in the INCLUDE and ICC environment variables, combined with how you use the following compiler options: /Ipath[;path] Specifies the #include search path. Note that for user include files, the directory of the source file is always searched first. /Xc[+|-] Stops the compiler from searching paths specified using /I. /Xi[+|-] Stop the compiler from searching paths specified by the INCLUDE environment variable. Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame ═══ 10.13. Creating a compiler listing ═══ At the very minimum, the listing will show the options used by the compiler, any error messages, and a standard header that shows:  The product number  The compiler version and release number  The date and time that the compilation began  A list of the compiler options in effect. Use one or more of the following options to control whether or not a listing file is produced, the type of information in the listing, and the appearance of the file: Option Description /Ls[+] Includes your source program in the listing file. /Li[+] Shows the included text after the user #include directives. /Lj[+] Shows the included text after both user and system #include directives. /La[+] Includes a table of all the referenced structure and union variables in the source program. /Lb[+] Includes a table of all structure and union variables in the program. /Le[+] Includes all expanded macros in the listing file. /Lx[+] Includes a cross-reference table that contains a list of the referenced identifiers in the source file together with the numbers of the lines in which they appear. /Ly[+] Includes a cross-reference table that contains a list of all identifiers referenced by the user and all external identifiers, together with the numbers of the lines in which they appear. Notes for using some of the above options:  The above options only modify the appearance of a listing; they do not cause a listing to be produced. Use them with one of the other listing file options, or the /Fl option, to produce a listing: /Le, /Li, /Lj, /Lp, /Lt, or /Lu.  If you specify any of the /Le, /Li, or /Lj options, you must also specify the /L, /Lf, or /Ls option.  If you specify the /Lj option, /Li[+] and /Li- have no effect. Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame ═══ 10.14. Optimizing for speed and size ═══ The VisualAge C++ compiler can perform many optimizations, such as local and global optimizations, function inlining, and instruction scheduling on object code. Use the /O+ option to generate code that executes as fast as possible. By default, optimization is turned off (/O-). When you specify /O, you can also specify: /Oc Optimize code for size as well as speed. /Op Perform optimizations that involve the stack pointer. Turned on by default when you specify /O. /Os Invoke the instruction scheduler. Turned on by default when you specify /O. By default, /O also sets /Oi to inline user functions qualified with the _Inline or inline keywords. The compiler can perform more complete optimization when you specify /Ol to invoke the intermediate code linker. Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame ═══ 10.15. Setting the source code language level ═══ You can set the language level of your source code to one of the following levels: ANSI - Compile according to a strict interpretation of the ANSI standard. Use this level when you want your code to be portable to other compilers. Compile with /Sa or use the #pragma langlvl(ansi) directive. SAA Level 2 - Compile according to the SAA Level 2 standard. Use this level when you want your code to be portable to other IBM compilers. Compile with /S2 or use the #pragma langlvl(saal2) directive. Extended - Allow extended language features, allow non-standard language usage. Use this level when you are compiling code ported from another compiler, or when you are compiling code that does not need to be portable. Compile with /Se or use the #pragma langlvl(extended) directive. Compatible - Allow older versions of the C++ language. Use this level when you are compiling older code. Compile with /Sc or use the #pragma langlvl(compat) directive. Note that a #pragma langlvl directive in your source code overrides any conflicting compiler options. When you set the language level, you also define the macro associated with that level. The SAA C standards conform to the ANSI standards, but also feature some additional elements. Note: If you will be compiling and running your code primarily on the personal computer platform, you should use the extended language level. Related Information:  The #pragma langlvl section of the Language Reference ═══ 10.16. Setting the calling convention ═══ The VisualAge C++ compiler supports six 32-bit calling conventions, and three 16-bit conventions: 32-bit: 16-bit: _Optlink _Far16 _cdecl _System _Far16 _Pascal _Pascal _Far16 _Fastcall _Far32 _Pascal _cdecl _stdcall Note: The _Far32 _Pascal convention can only be used in C programs and only when the /Gr+ option is specified. The default is _Optlink for calls to 32-bit code. You must explicitly specify a calling convention for all 16-bit calls. If you specify only _Far16, the convention defaults to _Far16 _cdecl. You can change the default for 32-bit code to _System by using the /Ms compiler option. The /Mp option explicitly sets the calling convention to _Optlink. You can also set the calling convention for individual functions using linkage keywords. For example, to declare sample as a function with the _System calling convention, you could use the following statement: int _System sample(int i); Note: You cannot change the calling convention for C++ member functions. Member functions always use the _Optlink convention. Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame Related Information:  The Calling Conventions section of the Programming Guide ═══ 10.17. Setting the stack size ═══ You can set the stack size in one of three ways:  Specify the /B"/STACK:size" compiler option.  Specify the /STACK:size linker option when you invoke the linker from the command line.  Specify the STACKSIZE statement in a module definition (.DEF) file for the first thread of an application; use the _beginthread function call for threads created later. The default stack size is 32K for the first thread. Setting the stack size using one of the options listed above overrides the default value. For example, specifying the linker option: /STACK:65536 sets the stack size to be 64K. If your program calls 16-bit code, you can set the stack for the 16-bit code using the #pragma stack16 directive. Because the 16-bit stack is allocated from the 32-bit stack, you must ensure that the 32-bit stack is large enough for both your 32-bit and 16-bit code. Related Tasks:  How do I set compiler options using WorkFrame  How do I set linker options using WorkFrame  How do I compile from the command line  How do I compile from within WorkFrame ═══ 11. Create Diskettes from CD-ROM ═══ The VisualAge C++ CD-ROM contains diskette images for 3.5 inch 1.44 MB format diskettes. The images are located in the IMAGES directory on the CD-ROM. You can create diskettes from these images to use as a backup to the CD-ROM, or to install on a machine without a CD-ROM drive: Important: If you create diskettes to install on other workstations, make sure you observe the license agreement as described in the License Information booklet. 1. Access the CD-ROM drive and change to the IMAGES directory. 2. Insert a 3.5 inch diskette in your diskette drive. Note that you can use 5.25 inch diskettes, but you must specify the /C option on the LOADDSKF command in the next step. 3. Copy the first diskette image (DISK1.IMG) to the diskette using the LOADDSKF utility, which is also located in the IMAGES directory. See below for syntax of the LOADDSKF command. 4. Remove the diskette and label it Diskette 1. 5. Repeat steps 2 to 4 for each of the diskette images. LOADDSKF runs on both DOS and OS/2, and the general syntax is: LOADDSKF [d:\path\]diskette.img a: [options] Where: d:\path\ Is the path of the diskette image file (in this case, the IMAGES directory). diskette.img Is the name of the diskette image file. a: Is the diskette drive where the target diskette is. options Are any of the following: /F  Format the target diskette to match the diskette image format. /Y  Skip the prompt of user input (y/n) when overwriting the diskette. /Y /Q  Skip the warning message when overwriting the diskette. /S  Do not beep when diskette has been created (silent mode). /C  Create 5.25 inch diskettes from the 3.5 inch images. We recommend that you use the /F option to ensure that your diskette images are formatted correctly; you may want to use the other options for convenience. ═══ 12. Create Files ═══ You can create the following files (Note that this is not an exhaustive list):  A compiler listing  Header files to work with both C and C++  A Module Definition file  An .EXE file  An .OBJ file  A device driver (.SYS)  Make files and dependency files  Library (.LIB) files  Runtime library (.DLL) files  Your own message files  A WorkFrame project Related Information  The Programming Guide  The User's Guide ═══ 12.1. Creating a compiler listing ═══ ═══ 12.2. Creating header files to work with both C and C++ ═══ Follow these guidelines to enable your new header files to work with both C and C++ code: 1. Rename any C or C++ specific keywords. 2. Add to the beginning of each header file: #if __cplusplus extern "C" { #endif 3. Add to the end of each header file: #if __cplusplus } #endif 4. Do not use _Packed in your code; use #pragma pack instead. 5. Do not use #pragma linkage in your code; use the linkage convention keywords instead. 6. Use typedefs for structures to be passed to 16-bit code and specify the typedef in a #pragma seg16 directive. 7. Specify the linkage on any identifiers that are pointers to functions. 8. Use the _Seg16 type qualifier to declare external pointers that will be shared between 32-bit and 16-bit code (and are declared in both). The _Seg16 qualifier directs the compiler to store the pointer as a segmented pointer (with a 16-bit selector and 16-bit offset) that can be used directly by a 16-bit application. You can also use the pointer in a 32-bit program; the VisualAge C++ compiler automatically converts it to a flat 32-bit pointer when necessary. ═══ 12.3. Creating a module definition file ═══ ═══ 12.4. Creating an .EXE file ═══ ═══ 12.5. Creating an .OBJ file ═══ ═══ 12.6. Creating make files and dependency files ═══ You could write your own make file, or use the WorkFrame MakeMake utility from either the WorkFrame project environment or from the command line. Both methods are described below. From a WorkFrame project: 1. Select MakeMake from the Project PullDown menu. The MakeMake window appears. 2. In the Actions ListBox, select the actions necessary for building the target of your project. 3. In the Source Files ListBox, select the source files on which the first action in the Actions ListBox is to be performed. 4. Select the Start PushButton. A window appears with the generated make file. You can edit the make file from this window. Note that this window will be in the form of a NoteBook if a dependency file was generated as well. In this case, use the NoteBook tabs to switch between the make file and the dependency file. From the command line: Enter makemake [options] on the command line, where options can be: /P Specifies the name of the project to be processed. You can use the path name or its persistent object ID (found in the /DESKTOP directory). /A Specifies the action to be used to build the target in the form ::. This option can be repeated if you have more than one build action to specify. /NOD Do not display the MakeMake window. /NOP Do not prompt via Message boxes. All errors are returned as error codes. /F Force the overwriting of make files regardless of whether the make file was modified since its last generation. /S Generate a separate dependency file. /D Save only the dependency file. Do not save the make file. Related Information:  The MakeMake section of the User's Guide ═══ 12.7. Creating .LIB files ═══ ;i2 refid=files.library (.LIB), creating To create a new library file, use the ILIB utility. The syntax for the ILIB utility is: ILIB [library] Specify the name of the library file you want to create on the command line (or at the Library name: prompt when using ILIB prompts). Note: A library file is automatically created if the library file name you specify is immediately followed by a command, comma, or semicolon. In this case, the prompt does not appear. Note that if the name you specify for the new library file already exists, ILIB assumes that you want to modify the existing file. Related Information:  The Creating and Maintaining Libraries with ILIB section of the User's Guide ═══ 12.8. Creating .DLL files ═══ ═══ 12.9. Creating my own message files ═══ You can use the MKMSGF program provided in the Toolkit. The MKMSGF program reads the input message file that you specify, and creates an output message file that DosGetMessage uses to display messages. At the OS/2 command prompt, enter: MKMSGF infile.txt outfile.msg [options] Use the outfile.msg file with DosGetMessage to display the message in your application. To see quick help on the MKMSGF program, enter MKMSGF /? on the OS/2 command line. Related Information:  The Toolkit Reference. ═══ 12.10. Creating a WorkFrame project ═══ ═══ 13. Create Data Access Methods ═══ Data Access Builder is an application development tool that you can use to create data access methods. Use these generated methods with the Data Access Builder classes which make up part of the VisualAge C++ Open Class Library to access a DB2/2 relational database. Using the Data Access Builder tools, you map your existing relational database tables to object interfaces. In a simple case, a relational database table maps to a class, and a column of the table maps to a class attribute. Once you have defined your mapping, you can generate code based on it. Note that the C++ objects that you create can be imported into the VisualAge C++ Visual Builder. You can start Data Access Builder using any of the following methods:  Double click on the Data Access Builder icon in the VisualAge C++ Tools folder.  Type icsdata.exe from an OS/2 command line, and press Enter.  From the PopUp menu on a WorkFrame project icon (for which the project uses the Data Access Builder actions profile), select from the Actions Cascade menu  Choose the DATABASE Cascade menu from any Project PullDown menu of any WorkFrame-integrated tool that uses the Data Access Builder actions profile. Related Information:  The Data Access Builder How Do I... information  The Data Access Builder User's Guide  The Visual Builder How Do I... information  The Visual Builder User's Guide  The Visual Builder Parts Reference ═══ 14. Create Help and Message Files ═══ You can create the following (Note that this is not an exhaustive list):  Your own message files  Online help for applications  Online documentation ═══ 14.1. Creating my own message files ═══ ═══ 14.2. Writing online help for applications ═══ You create the source information in the same manner as you would create online documentation. However, you must create help tables which map the resource number of the user interface objects to the actual information tables. For more information on how to do this, see the Information Presentation Facility (IPF) Guide and Reference. Related Tasks:  How do I create online documentation ═══ 14.3. Creating online documentation ═══ The Information Presentation Facility (IPF) is a Toolkit tool that you can use to create online information, to specify how it will appear on the screen, to connect various parts of the information, and to provide help information that can be requested by the user. IPF features include:  A tagging language lets you specify the format of text and provides a way to connect information and customize the information display.  A compiler that creates online documents and help windows.  A viewing program (view.exe) that displays formatted online documents (view). This program is part of the OS/2 operating system. The syntax for the IPF compiler command is: IPFC source_file [/options] [output_message_file] Enabling help for applications requires programming code that communicates with IPF and with the PM APIs to display help windows. For more information on how to do this, see the Information Presentation Facility (IPF) Guide and Reference. ═══ 15. Debug my Heaps ═══ VisualAge C++ provides two sets of functions for debugging your heap usage:  Debug versions of all memory management functions  Heap-checking functions similar to those provided by other compilers Which should you use? Both sets of debugging functions have their benefits and drawbacks. Which function you choose to use depends on your program, your problem, and your preference. For example, you could add calls to heap-checking functions in places where you suspect possible memory problems. If the heap turns out to be corrupted, then you may want to rebuild with the /Tm option. ═══ 15.1. Debugging heaps using debug versions ═══ The debug version calls _uheap_check to check the heap used in the call, and records the file and line number where the memory was allocated or freed. You can then use _dump_allocated or _dump_allocated_delta to display information about currently allocated memory blocks. Information is printed to stderr; you can change the destination with the _set_crt_msg_handle function. You can use debug memory management functions for any type of heap, including tiled and shared memory. To use debug versions, specify the /Tm option. If you parenthesize the name of a memory management function, the function is not mapped to the debug version; however, this does not apply to the C++ new and delete functions, which are mapped to their debug versions regardless of parentheses. You can specify both /Gt and /Tm together, to map regular memory management functions to tiled debug versions (for example, _debug_tmalloc). Note: You can mix debug and non-debug memory management functions. ═══ 15.2. Debugging heaps using heap-checking functions ═══ VisualAge C++ also provides new functions for validating your heaps: _uheapchk, _uheapset, and _uheap_walk. Both _uheapchk and _uheapset check the specified heap for minimal consistency; _uheapchk checks the entire heap, while _uheapset checks only the free memory. _uheapset also sets the free memory in the heap to a value that you specify. _uheap_walk traverses the heap and provides information about each allocated or freed object to a callback function that you provide. You can then use the information in a way that you like. These heap-checking functions are defined in umalloc.h, while the regular versions of these functions are defined in malloc.h. Note: These heap-checking functions are not controlled by a compiler option, so you can use them in your program at any time. ═══ 16. Debug my Programs ═══ The VisualAge C++ Debugger uses Presentation Manager (PM) window services to help detect and diagnose errors in code developed in IBM 32-bit C/C++. Use the Debugger to run your program, set breakpoints, examine message queues, and monitor variables, registers, storage and the call stack. To start the Debugger:  Double-click on the Debugger icon found in the Tools folder which is located in the VisualAge C++ desktop folder.  From the WorkFrame project environment, select Debug from the WorkFrame PullDown menu.  From other components of VisualAge C++, select Debug from the Project PullDown menu.  From the command line, type: icsdebug. Related Tasks:  How do I compile for debugging  How do I link for debugging Related Information:  The Debugger How Do I... information  The Debugging section of the User's Guide ═══ 17. Delete/Add VisualAge C++ Components ═══ ═══ 18. Determine What Classes are in the Open Class Library ═══ Use the VisualAge C++ Browser facility to determine which classes are contained in the VisualAge C++ Open Class Library. From the Browser Load  Cascade menu located on the File PullDown menu, select the type of class that you want to look for:  Application Support Classes  Complex Mathematics Classes  Collection Classes  Database Access Classes  I/O Stream Classes  User Interface Classes Selecting one of the above will produce a list of all classes defined for that group of classes.  You can use the Browser to graphically view the entire structure of these classes, by choosing the Show Inheritance Graph menu item from the Actions PullDown menu.  You can view the members of a class and its base classes by clicking Mouse Button 2 on any class object and selecting the List Members with Inheritance menu item.  You can view the include file graph by selecting the Show Include File Graph menu item from the Actions PullDown menu.  You can see the definition of a class, function, type or variable by clicking Mouse Button 2 on the object and choosing the Edit Definition menu item.  You can list all defined objects in a file by clicking Mouse Button 2 on a file object and selecting the List Defined Objects menu item.  You can list the implementing file of a class by selecting the class with Mouse Button 2 and choosing the List Implementing Files menu item. Related Information:  The Browser section of the User's Guide  The Browser How Do I... Information  The Open Class Library User's Guide  The Open Class Library Reference ═══ 19. Develop with WorkFrame ═══ To use WorkFrame, you must first create a project. If you have existing projects, you can:  Copy a WorkFrame project to diskette  Migrate old WorkFrame projects You can perform all tool activities from within WorkFrame:  Edit your source code  Compile from within WorkFrame  Link from within WorkFrame  Debug your programs  Analyze performance  Browse your programs  Map existing relational database tables to object interfaces You can also set compiler and linker settings from within the WorkFrame environment:  Set compiler options using WorkFrame  Set linker options using WorkFrame Note: This is not an exhaustive list of tasks used to develop with WorkFrame. Related Information:  The WorkFrame How Do I... information  The WorkFrame section of the User's Guide ═══ 19.1. Creating WorkFrame projects ═══ To quickly create WorkFrame projects: 1. Open the VisualAge C++ desktop folder. 2. Double-click on the Project Smarts object to open a catalog of project skeletons for common types of application. 3. Choose the type of application you want to create from the catalog by double-clicking on the listed item. 4. Click on the Create PushButton to continue with the specification of your new project. Alternatively: 1. Open the Templates folder (usually located on your desktop). 2. Drag a WorkFrame Project icon onto your desktop to create a project icon on your desktop. In either case, you can further customize the created project. Related Information:  The WorkFrame section of the User's Guide  The WorkFrame How Do I... information ═══ 19.2. Copying a WorkFrame project to diskette ═══ If your project is not very large: 1. On the source machine, drag the project icon onto your diskette drive icon. If there is a diskette in the drive, the project will be copied. 2. On the target machine, insert the copied diskette. 3. Double-click on the diskette drive icon. 4. Drag the project icon to the desktop. If you have a very large project, then you can compress the project, and split the compressed file across several diskettes, if required: 1. Compress the project using a compression program that preserves extended file attributes (such as zip and unzip programs). Project files are found in the \DESKTOP directory on your boot drive. 2. If your compressed file is very large and your compression program supports splitting files, you can split the compressed file into smaller files to fit on diskette. 3. Copy the compressed file(s) onto a diskette. 4. Uncompress the file(s) under the \DESKTOP directory on the target machine. ═══ 19.3. Migrating old WorkFrame projects ═══ If you have WorkFrame projects that were created in WorkFrame Version 1.x or Version 2.x, and want to transform them into the format that the current version uses: 1. Double-click on the Migrate Projects icon found in the Tools folder of the VisualAge C++ desktop folder. 2. Decide whether you want to migrate projects from Version 1.x or Version 2.x. 3. Decide which projects you want to migrate. The original projects are not modified. The new projects are put into a Migration folder on the desktop. 4. Decide if you want to migrate just the basic project settings, or the settings and the action profiles (which determine the contents of the PopUp and PullDown menus). Because WorkFrame Version 3.0 defines many default actions, you might want to migrate just the project itself, unless you have customized the action profiles significantly. 5. To migrate WorkFrame Version 1.x projects: Select the Change Directory PushButton to locate the directories where the projects are located. When you select OK, the migration process is started. 6. To migrate WorkFrame Version 2.x projects: Select the drives on which the projects are located, and select the Find Projects PushButton to find the projects. Once you have found one or more projects, select the ones you want to migrate, and select the Migrate PushButton to perform the automatic phase of the migration. 7. After the automatic migration is finished, follow these manual steps for each project: a. Archive the old version (optional). b. Rename the new version and move to another folder (optional). Related Information:  The WorkFrame section of the User's Guide  The WorkFrame How Do I... information ═══ 19.4. Compiling from within WorkFrame ═══ ═══ 19.5. Linking from within WorkFrame ═══ ═══ 19.6. Setting compiler options using WorkFrame ═══ If you have installed the WorkFrame product, you can set options as follows: 1. Double-click on the project icon to open the WorkFrame project environment. 2. From the Options menu, select the Build Smarts menu item. The Build Smarts window appears, in which you can select a standard task you want to build for. The options appropriate for that task are set automatically when you select the OK PushButton. If you want to set options on an individual basis, as well as by general task, then do the following: a. Select the Compiler menu item from the Options PullDown menu to display the Compiler Options NoteBook. b. Select options in the NoteBook. Turn the pages to see all the options (there can be several pages under one tab). c. Select the OK PushButton when you are done. The next time you build your project, the options you selected are used. Related Information:  The WorkFrame section of the User's Guide  The WorkFrame How Do I... information ═══ 19.7. Setting linker options using WorkFrame ═══ If you have installed the WorkFrame product, you can set linker options using the options dialogs. You can use the dialogs when you create or modify a project.  Double-click on the project icon to open the WorkFrame project environment.  Select the Linker menu item from the Options PullDown menu to display the Linker Options NoteBook.  Select options in the NoteBook. Turn the pages to see all the options (there can be several pages under one tab).  Select the OK PushButton when you are done. Options you select while creating or changing a project are saved with that project. Related Information:  The WorkFrame section of the User's Guide  The WorkFrame How Do I... information ═══ 20. Edit Files ═══ The VisualAge C++ Editor can be used to edit all kinds of files, including C and C++ files. You can also use the Editor to start other tasks, by selecting choices from the Project or Browser PullDown menus. From the editor, you can perform a wide variety of tasks, including compiling, linking, debugging, and browsing your program. To start the Editor:  Select the Editor icon from the Tools folder located in the VisualAge C++ desktop folder.  Select the Edit menu item from any tools Project PullDown menu.  With Mouse Button 2, select a file object in the WorkFrame environment, and select the Edit menu item from the PopUp menu. Related Information:  The Editor How Do I... Information  The Editor section of the User's Guide ═══ 21. Get Support ═══ To contact VisualAge C++ Service and Support: Telephone Support in the USA and Canada VisualAge C++ has a free 60-day Getting Started period (GSP) to help you with installation, usage, and how-to problems. Call 1-800-237-5511. The 60-day period starts on the date of your first call, and is offered 9am to 5pm (in your time zone), Monday through Friday. If you need service outside of these hours during the GSP, services charges apply. Call 1-800-237-5511 for details. After your 60-day GSP, we offer a wide menu of service options tailored to a full spectrum of customer needs. Again, call 1-800-237-5511 for details. Quite often, you may not need a technical support, for example when you have questions about CSD levels and availability, registration cards, or beta tests. In recognition of these questions, our automated response system contains a wealth of useful information. You can also receive much of that information by fax. The response system is available 24 hours a day, 7 days a week. Call 1-800-668-2853. (Outside of North America, you can access the same system at 416-448-4363). Telephone Support Outside North America For local country support, please contact your IBM branch for details. Electronic Support - Worldwide You can also contact VisualAge C++ Support electronically. There is no charge for this service, other than what you normally pay for your electronic access.  Compuserve (OS2DF1)  INTERNET - va_cpp@vnet.ibm.com - workframe@vnet.ibm.com for WorkFrame-specific questions  IBMLink/ServiceLink - VA C++ forum - ETR (electronic reporting of problems)  TalkLink - VA C++ forum - ETR (electronic reporting of problems) If you frequent the Internet, you can also contact other knowledgeable VisualAge C++ users on the USENET newsgroups. (VisualAge C++ discussions often appear in the comp.os.os2.programmer hierarchy). Other Defect Reporting Channels in the USA and Canada You can also report possible VisualAge C++ code-related problems using any of the following methods:  FAX: 1-800-426-8602  MAIL: IBM Corp Personal Systems Support Family 11400 Burnet Road Internal Zip 2901 AUSTIN, TX 78758  ELECTRONIC: CompuServe - 76711,611 Other Defect Reporting Channels Outside the USA and Canada Other IBM countries offer mail-in and fax support. Please contact your IBM branch for details. ═══ 22. Improve Compiler Performance ═══ You can speed up some compilations by doing one or all of the following:  If the VisualAge C++ directories are at the end of the LIBPATH, PATH, INCLUDE, and so on, the compiler or linker must first search through all of the other directories before it finds the required DLLs, header files, and so on. Therefore, the compiler and linker will find the VisualAge C++ directories faster if you move them to the beginning of LIBPATH, PATH, INCLUDE, etc..  Ensure that the compiler is preloaded with the /Tl option (it is preloaded by default). This option keeps the compiler components loaded in memory.  If you are using static linking to the VisualAge C++ libraries, try dynamic linking.  Use precompiled header files. See the User's Guide for details on how to structure your files so the compiler can take full advantage of the precompiled headers.  Turn off all optimizations.  If you are using the HPFS file system, set the IFS statement in your config.sys file to: IFS=c:\os2\hpfs.ifs /cache:2048 /crecl:64 This allows OS/2 to keep frequently-used header files in memory between compilation, which can greatly reduce the amount of time it requires the compiler to process them.  Add more RAM to your system. In a memory-constrained environment, OS/2 spends more time swapping data to disk, which increases compilation times tremendously. Additional RAM allows the compiler and its data to remain in memory, which can make your builds run more quickly.  Define a virtual disk (VDISK or RAM disk) with the OS/2 VDISK device driver. It creates a disk from your system's RAM. For example, placing this statement in your config.sys file: DEVICE=C:\OS2\VDISK.SYS 2048,,256 allocates a virtual disk of 2M with 256 directory entries. You can then copy all the library and header files you need for compiling and linking to this disk and set your LIB and INCLUDE variables to point to it before any other directory. Because these files are already in memory, your compile and link times will improve. (Do not put the compiler executable files there; the compiler preloads them into memory by default, so you would then have two copies in memory.) However, there are drawbacks to using a VDISK. The data on it is lost when you reboot. Also, memory allocated for a VDISK is unswappable memory space, meaning it cannot be used as normal memory space by applications. Because C++ compilations can require a lot of memory, putting memory into a VDISK could cause excessive memory paging and slow down your compilation. If you have a large VDISK, it may be to your advantage to eliminate it or make it smaller to provide more available memory to the compiler  Minimize dependencies between source files so that changes made to one file don't require you to recompile all your files.  For C++ programs specifically: - Create abstract objects that contain only public methods and make your real objects descendents of those objects. This approach reduces the amount of total source code in compiles that do not need to refer to the real objects. - In .HPP files, only include those files you need. For example, if all that the .HPP file for class B needs to know about class A is that class B contains a pointer to a class A-type object, put class a; (rather than #include "a.hpp") in B.HPP. Note: This approach would still allow you to put #include "a.hpp" in B.CPP. ═══ 23. Learn About SOM and DirectToSOM ═══ System Object Model (SOM) defines an interface between programs, or between libraries and programs, so that an object's interface is separated from its implementation. SOM allows classes of objects to be defined in one programming language and used in another, and it allows libraries of such classes to be updated without requiring client code to be recompiled. To learn all about SOM, see the IBM System Object Model Programming Guide. ═══ 24. Learn More About Object-Oriented Programming ═══ Many books have been written about the C++ language and related programming topics. The authors use varying approaches and emphasis. The following is a sample of some non-IBM C++ publications that are generally available. This sample is not an exhaustive list.  The Annotated C++ Reference Manual by Margaret A. Ellis and Bjarne Stroustrup, Addison-Wesley Publishing Company.  C++ Primer by Stanley B. Lippman, Addison-Wesley Publishing Company.  Object-Oriented Design with Applications by Grady Booch, Benjamin/Cummings.  Object-Oriented Programming Using SOM and DSOM by Christina Lau, Van Nostrand Reinhold.  OS/2 C++ Class Library: Power GUI Programming with C Set ++ by Kevin Leong, William Law, Robert Love, Hiroshi Tsuji, and Bruce Olson, Van Nostrand Reinhold. Note: IBM does not specifically recommend any of these books, and other C++ books may be available in your locality. ═══ 25. Link my Programs ═══ You can link your programs in four ways:  From within WorkFrame  From the command line  Through the compiler  From a make file You can link with the following file types:  With .LIB files  With .DLL files You can link to generate information for:  Debugging  Browsing  Analysis You can use the linker to create:  An .EXE file  A .DLL file  A device driver  A module definition (.DEF) file  A MAP file And you can set linker options from within WorkFrame. Note: This is not an exhaustive list of tasks used to link your programs. Related Tasks:  How do I compile and link multithread programs Related Information:  The Linking section of the User's Guide ═══ 25.1. Linking from within WorkFrame ═══ In general, you should perform the link action when you build your project target. However, if you want to link individual .OBJ files: 1. Select all the .OBJ files that you want to link together. Note that if you chose to link multiple files, you must also have a module definition (.DEF) file defined and selected. 2. Click Mouse Button 2 on the background of the WorkFrame environment, or select the Selected PullDown menu. 3. Select the Link menu item. Note that linking is also done as part of the Build process when you build your project's target. Related Tasks:  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The WorkFrame How Do I information  The WorkFrame section of the User's Guide ═══ 25.2. Linking from the command line ═══ The syntax for the ILINK command is: ILINK [options] filename [directory\] [@responsefile] Specify the ILINK command followed by any sequence of options, file names, or directories, separated by space or tab characters. Note that you must specify at least one object file. The directories you specify become part of the linker's search path, before any directories set in the LIB environment variable. You can specify a definition file to describe the characteristics of an application or library, including imports and exports. If you are using a response file, then it should always be specified last. Leave any other parameter blank to accept the default entry for it. You can end the command line at any point with a semicolon (;), to accept the default for all remaining parameters. Note: If ILINK cannot find a file, it stops linking. The linker does not assume the .OBJ extension for a file: if you specifya file with no extension, then the linker looks for that file with no extension. Related Tasks:  How do I respond to ILINK prompts  How do I link from WorkFrame  How do I link through the compiler  How do I link from a make file ═══ Responding to ILINK prompts ═══ To have the linker prompt you for ILINK entries, specify /NOFREE at the start of the command line (or in the ILINK environment variable), then you can use the LINK386-style syntax to specify input to the linker. For each prompt, simply enter the same input that you would enter on the command line, and press Enter. These are the ILINK prompts: Object Modules [.obj]: Run File [basename.*]: List File [targetname.map]: Libraries [.LIB]: Definitions File [nul.def]: basename defaults to the name of the first object file you specify. targetname defaults to the name of the run file. The prompt displays the default response in square brackets ([ ]). Press Enter to accept the default response to a prompt and continue to the next prompt. To accept default responses for all remaining prompts, enter a semicolon (;). Note that:  To extend input to a new line, type a plus sign (+) as the last character on the current line. When the same prompt appears on a new line, you can continue. You cannot split a file name across lines.  You must enter at least one object file.  You can specify options anywhere on any response line. Each option must begin with a forward slash (/), or a dash (-).  At any prompt, you can specify responses both for that prompt and for subsequent prompts, by separating the responses with commas (,). ═══ Linking using response files ═══ Instead of specifying linker input on the command line, you can put options and file name parameters in a response file. You can combine the response file with options and parameters on the command line, but the command line options and parameters must appear before the response file; the linker ignores anything on the command line after the response file. In the response file, separate responses with commas, or put each response on a separate line. Then, when you invoke ILINK, use the following syntax: ILINK @responsefile where responsefile is the name of the response file. The @ symbol indicates that the file is a response file. If the file is not in the working directory, specify the path for the file as well as the file name. If ILINK cannot find a file, it stops linking. If the file does not contain responses for all the prompts and does not end in a semicolon (;), then ILINK displays the appropriate prompt and waits for you to supply a response. You must provide the file name for at least one object file. You can use special characters in the response file the same way you would use them in responses entered at the keyboard. For example, you can extend input to a new line by using the plus sign (+) and choose default responses for all remaining prompts by using a semicolon (;). ═══ 25.3. Linking through the compiler ═══ When you invoke the VisualAge C++ compiler (using the icc command), it compiles the object files from your source code and then automatically starts the linker, to link the object files into an .EXE or .DLL file. Use the /B compiler option to pass options to the linker. By default, the compiler invokes the linker with the following options: /NOFREEFORMAT Use the LINK386-compatible syntax, instead of the free-format syntax. for more information on the free-format syntax. for more information on the LINK386-compatible syntax. /BASE:65536 Specify the starting address of the program. For .DLL files, this results in a smaller and potentially faster executable, if the specified address is free when the .DLL is loaded. For .EXE files, the OS/2 operating system always loads executable programs at 64K. You can give the linker the address 65536 (or 0x10000) to let the linker know where the program will be loaded, so it can resolve relocation information at link time, resulting in a smaller .EXE file. /PMTYPE:VIO Create program that is compatible with Presentation Manager. In addition, some compiler options generate equivalent linker options: /Fb Generate browser information. Passes /BROWSE to the linker. /Fm Generate linker map file. Passes /MAP to the linker. /Gk Resolve template functions in old object files. Passes /OLDCPP to the linker. /Gl Remove unreferenced functions. Passes /OPTFUNC to the linker. /Gn Hide default library information from the linker. Passes /NODEFAULTLIBRARYSEARCH to the linker. /Q Suppress product information at start of compile. Passes /NOLOGO to the linker. /Ti Generate debugger information. Passes /DEBUG to the linker. Related Tasks:  How do I link from WorkFrame  How do I link from the command line  How do I link from a make file Related Information:  The Setting Compiler Options section of the User's Guide  The Linker Options section of the User's Guide ═══ 25.4. Linking from a make file ═══ Use a make file to organize the sequence of actions (such as compiling and linking) required to build your source. You can then invoke all the actions in one step: NMAKE makefile_name The NMAKE utility saves you time for it will only perform actions on those files that have changed, and on the files that incorporate or depend on the changed files: You can write your own make file, or you can use the WorkFrame MakeMake utility to write the make file for you. Related Tasks:  How do I create make file and dependency files  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler ═══ 25.5. Linking with .LIB files ═══ The linker uses library (.LIB) files to resolve external references from code in the object (.OBJ) files. When the linker finds a function or data reference in a .OBJ file that requires a module from a library, the linker links the module from the library to the output file. The compiler embeds the names of needed libraries (called default libraries) in object files. You do not need to specify these libraries: the linker searches them automatically. Specify library files only when:  You want to use libraries other than the default libraries. Libraries you specify are searched ahead of the default libraries.  You want to specify the default library with its full path, because the default library is not in the current directory, and not in a directory specified in the LIB environment variable. You can also specify a path to a directory, without specifying a file name, to have the linker search that directory before the directories in the LIB environment variable. To ignore the default libraries, use the /NODEFAULTLIBRARYSEARCH option. Use the option with care, because most compilers expect their object files to be linked with default libraries. If you want to include all of a library's objects in the output file, instead of only the required ones, you must link with the /NOFREE option, to use the LINK386-compatible syntax. You can then enter the library name as an object file. Related Tasks:  How do I work with libraries  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section in the User's Guide ═══ 25.6. Linking with .DLL files ═══ A dynamic link library (DLL) file contains executable code for common functions, just as an ordinary library (.LIB) file does. However, when you link with a DLL, the code in the DLL is not copied into the executable (.EXE) file. Instead, only the import definitions for DLL functions are copied. At run time, the dynamic link library that contains the functions is loaded into memory, along with the .EXE file that references them. There are two ways to link with a DLL:  Using a .DEF file to define functions your object files import from the DLL.  Using an import library, created with the IMPLIB utility, that allows the linker to determine which functions your object files need to import from the DLL. Related Tasks:  How do I work with DLLs  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section in the User's Guide ═══ 25.7. Linking for debugging ═══ To link your files in order to generate debug information which will allow you to debug the file with the Debugger: 1. Compile with the /Ti option. 2. Link with the /DEBUG option. When you specify /DEBUG, /BROWSE is turned on by default. Note: Linking with /DEBUG increases the size of the executable output file. Related Tasks:  How do I debug my programs  How do I debug my heap  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section in the User's Guide  The Debugging section of the User's Guide  The Debugger How Do I... information ═══ 25.8. Linking for browsing ═══ First, compile with the /Fb compiler option, then link your files with the /BROWSE to add browse information to the load module ILINK generates. The browse information is used by the Browser to allow you to view your program's class structure and component relationships. Note: The /BROWSE option is automatically turned on when you specify /DEBUG. Related Tasks:  How do I browse my files  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section of the User's Guide  The Browser How Do I... information  The Browser section of the User's Guide ═══ 25.9. Linking for analysis ═══ To include debug information in the executable that allows you to analyze its performance: 1. Compile with the /Ti and /Gh options. 2. Link with the /DEBUG linker option. ILINK will embed symbolic data and line number information in the output file. Note that when you specify the /DEBUG linker option, the /BROWSE linker option is turned on by default. Note: Linking with /DEBUG increases the size of the executable output file. Related Tasks:  How do I analyze performance  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section in the User's Guide  The Performance Analyzer How Do I... information  The Performance Analyzer section of the User's Guide ═══ 25.10. Creating an .EXE file ═══ ILINK produces .EXE files by default. To reduce the size of the .EXE file and improve its performance, use the following options:  /ALIGNMENT:value to set the alignment factor in the output file. Set value to smaller factors to reduce the size of the executable, and to larger factors to reduce load time for the executable. By default, the alignment is set to 512.  /EXEPACK to compress the file. Note: Set /EXEPACK:2 for executables that will run only on OS/2 v3.0 and later. Do not set a value for /BASE; the load address for the executable is always 0x00010000. Any other value will produce a warning, and will not be used. If you do not specify an extension for the output file name, ILINK automatically adds the extension .EXE to the name you provide. If you do not specify an output file name at all, ILINK generates an .EXE file with the same file name as the first .OBJ file it linked. If you are using a module definition (.DEF) file, you can include a NAME statement to provide a name for the application. The .DEF file should not contain a LIBRARY, VIRTUAL DEVICE, or PHYSICAL DEVICE statement. Related Tasks:  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section of the User's Guide ═══ 25.11. Creating a .DLL file ═══ To produce a DLL as output, compile the object files with the /Ge- compiler option, and specify the LIBRARY statement in your module definition (.DEF) file. To reduce the size of the DLL and improve its performance, use the following options:  /ALIGNMENT:value to set the alignment factor in the output file. Set value to smaller factors to reduce the size of the DLL, and to larger factors to reduce load time for the DLL. By default, the alignment is set to 512.  /EXEPACK to compress the file. Note: Set /EXEPACK:2 for DLLs that will run only on OS/2 v3.0 and later. If you use the /BASE option, set /BASE:0x12000000 (or a lesser value), and provide a separate value for each DLL. For DLLs, setting a /BASE value can save load time when the given load address is available. If the load address is not available, the /BASE value is ignored, and there is no load time benefit. Use the _Export keyword, or the EXPORTS statement in a module definition file, to specify which functions you want to make available to other executables. Once you have produced the DLL, you can produce an executable that links to the DLL. This process can be done in two ways:  Using a .DEF file. Provide a .DEF file when you create the executable. In the .DEF file, use the IMPORTS statement to specify which of the DLL's functions your object files need.  Using an import library. Use the IMPLIB utility to create an import library. When you use an import library, you no longer need to use the IMPORTS statement. ILINK determines which functions your object files need during the linking process. Related Tasks:  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section of the User's Guide ═══ 25.12. Creating a device driver ═══ You can produce both physical device drivers and virtual device drivers:  A physical device driver (.SYS) allows the operating system to interact with a system peripheral, such as a monitor or printer.  A virtual device driver (.SYS or .VDD) allows the operating system to handle input and output with multiple DOS or WIN-OS/2 sessions. Each session can then act as if it has complete control of the input or output device, while actually sharing the control with other sessions. To produce a device driver file (.DRV or .VDD) as output, specify the PHYSICAL DEVICE or VIRTUAL DEVICE statement in your module definition (.DEF) file. If you are creating a physical device driver, use the SEGMENTS statement to specify which segments have I/O privilege. If you are creating a virtual device driver, compile with the options /Gr+ and Rn+, and use the subsystem libraries. Related Tasks:  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section of the User's Guide ═══ 25.13. Creating a module definition file ═══ A module definition (.DEF) file contains one or more module statements. These statements:  Define various attributes of your executable output file  Define attributes of code and data segments in the file  Identify data and functions that are imported into or exported from your file When you create a module definition file, follow these rules:  Use a NAME, LIBRARY, VIRTUAL DEVICE, or PHYSICAL DEVICE statement to define the type of executable output you want. You can only use one of these statements, and it must precede all other statements in the .DEF file.  Begin comment lines with a semicolon (;).  Enter all module definition keywords in UPPERCASE letters.  Do not use module definition keywords, or reserved words, as a text parameter to a statement. Related Tasks:  How do I link from WorkFrame  How do I link from the command line  How do I link through the compiler  How do I link from a make file Related Information:  The Linking section of the User's Guide  Creating Module Definition Files of the User's Guide ═══ 25.14. Generating a MAP file ═══ Specify /MAP to generate a map file, which lists the object modules in your output file; segment names, addresses, and sizes; and symbol information. If you do not specify a name for the map file, the map file takes the name of the executable output file, with the extension .map. To prevent the map file from being generated, specify the /NOMAP option. Specify /LINENUMBERS to include source file line numbers and associated addresses in the map file. Related Information:  The Linking section in the User's Guide ═══ 25.15. Setting linker options using WorkFrame ═══ ═══ 26. Migrate Files ═══ With VisualAge C++, you can migrate the following:  Headers from 16-bit to 32-bit C or C++  Headers from 32-bit C Set/2 to 32-bit VisualAge C++  Old WorkFrame projects Note: Note that this is not an exhaustive list. ═══ 26.1. Migrating headers from 16-bit to 32-bit C or C++ ═══ The following section describes the changes you need to make to existing 16-bit C headers for them to work with both 32-bit C and C++ code. Structures 1. Add #pragma pack statements around declarations of structures that will be passed to or from 16-bit code. Do not use the _Packed keyword because it is not supported by C++. 2. Declare integers in the structures as short or long, not int, so that the structures have the same size and layout in both 16-bit and 32-bit code. 3. Create typedefs for your structures, and use #pragma seg16 on those typedefs to specify that those structures should not cross a 64K boundary when laid out in memory. 4. Any structure members that are pointers must be qualified with the _Seg16 type qualifier. For example, far * would be translated to * _Seg16. This may even need to be done recursively if the 16-bit code will be manipulating the object pointed at. Function Prototypes 1. Prototype your functions using the linkage convention keywords. Do not use #pragma linkage because it is not supported in C++. 2. When you use a function pointer as an argument to a second function, specify the linkage of the function pointed at in the second function's prototype. This avoids errors when the /Mp or /Ms compiler options are used to set the default linkage. 3. If you pass a pointer to a 16-bit function as a member of an aggregate, array, or class, you must qualify the pointer with _Seg16. The _Seg16 keyword is also required if you use two or more levels of indirection (for example, a pointer to a pointer). If you pass the pointer directly as a parameter, the compiler automatically converts it to a 16-bit pointer and the _Seg16 keyword is not required. Required Conditional Compilation Directives The following directives must be added to the beginning of each header file: #if __cplusplus extern "C" { #endif The following directives must be added to the end of each header file: #if __cplusplus } #endif ═══ 26.2. Migrating headers from 32-bit C Set/2 to 32-bit VisualAge C++ ═══ You need to make the following changes to your existing header files for them to work with both C and C++ code: 1. Remove any use of the _Packed keyword, and replace it with the appropriate use of #pragma pack. C++ does not support _Packed. 2. Remove any use of #pragma linkage and add the appropriate linkage convention keyword to the prototype. C++ does not support #pragma linkage directives. In addition, add the following to the beginning of each header file: #if __cplusplus extern "C" { #endif And, add the following to the end of each header file: #if __cplusplus } #endif ═══ 26.3. Migrating old WorkFrame projects ═══ ═══ 27. Optimize for Speed and Size ═══ ═══ 28. Set Runtime Environment Variables ═══ There are two kinds of "runtimes" for which variables can be set:  The runtime in which the compiler and tools run (when you edit, build and debug the your application).  The runtime in which the resulting (built) application runs. Note: You need to be aware of both runtimes.  In the first case for the compiler and tools to perform successfully together, and  In the second case to ensure your application does not behave in an unexpected manner. ═══ 28.1. For the compiler and tools ═══ The VisualAge C++ compiler checks the OS/2 environment variables for path information and for the default values of compiler options.  If the VisualAge C++ installation program updated your config.sys file, many of the environment variables already have values for the compiler to use. The following OS/2 environment variables affect the operation of the VisualAge C++ compiler during compilation: DPATH, ICC, ILINK, INCLUDE, LIBD, PATH, and TMP. Note that if you did not have VisualAge C++ update your config.sys file, a file called config.add is created, and you can mirror these changes in your config.sys file.  If the program did not update config.sys, you can set these values by running the csetenv.cmd file in your OS/2 session before using the compiler. Note that if you double-click on the C/C++ Window icon in the VisualAge C++ desktop folder, then this command file is automatically run. Some environment variables, for example ICC, are optional. They are not added to your config.sys, file or to csetenv.cmd for you. If you chose not to modify your config.sys file at the time you installed VisualAge C++, the LIBPATH statement, the DEVICE statement, and numerous other environment variables required for one or more components to work properly, will not be set correctly in your config.sys file. Instead, the necessary updates were placed in a file called config.add. You can modify your config.sys file after install by mirroring the updates in the config.add. ═══ 28.2. For the application that you have Built ═══ You need to be aware of the following variables in your application's runtime, for they can affect the behaviour of your application and lead to unexpected results if not taken into account.  PATH  LOCPATH  LC Environment Variables  DPATH  LIBPATH  TMP  TEMPMEM  COMSPEC  TZ Most of these variables can be set:  from the command line,  in your CONFIG.SYS file,  in a command file using the SET command, or  from within your program using the putenv function. You can put an optional semicolon at the end of the commands that set the environment variables so that you can later append values to the variables from the command line. The functions that access these environment variables are not available when you use the subsystem libraries. To access the environment variables when using the subsystem libraries, you must use OS/2 APIs. Related Tasks:  How do I change my config.sys file for VisualAge C++ Related Information:  The PM Programming Reference for more information about OS/2 APIs.  The OS/2 Command Reference.  For more information on environment variables in general, see the OS/2 Master Help Index. ═══ 29. Specify whether I want an EXE or DLL ═══ Use the /Ge- compiler option to create DLLs and the /Ge+ compiler option to create EXEs. The /Ge- option causes the compiler to generates a reference to _dllentry for every module compiled. The /Ge+ option genereates a reference to _exeentry only if a main function is found in the source. If no main function is included, no linking reference is generated. If you want to create a library of objects that can be linked into either an executable file or a DLL, use the /Ge+ option when you compile. Typically, these objects do not contain a reference to main. If they do, you can override the /Ge option when you link your files. See the Programming Guide for information on how to override the /Ge option. Related Tasks:  How do I set compiler options using WorkFrame  How do I compile my programs ═══ 30. Trace my Programs ═══ ═══ 31. Understand my Program's Class Hierarchy ═══ Use the VisualAge C++ Browser to help you understand a program's class hierarchy structure. With the Browser, you can:  View a class hierarchy  View include file graphs  View members of a class  List implementing files  List objects defined in a file Related Tasks:  How do I browse my programs  How do I determine what classes are in the VisualAge C++ Open Class Library Related Information:  The Browser How Do I... information  The Browser section of the User's Guide ═══ 32. Use Templates ═══ The recommended way to instantiate templates is to structure your program for their automatic instantiation. To use this facility: 1. Declare your template functions in a header file using class or function templates, but do not define them. Include the header file in your source code. 2. For each header file, create a template-implementation file with the same name as the header and the extension .c. Define the template functions in this template-implementation file. The function definitions in your template-implementation file can be explicit definitions, template definitions, or both. Any explicit definitions are used instead of the definitions generated by the template. 3. If you have other declarations that are used inside templates but are not template parameters, you must place or #include them in either the template-implementation file or one of the header files that will be included as a result of the above three steps. Define any classes that are used in template arguments and that are required to generate the template function in the header file. If the class definitions require other header files, include them with the #include directive. The class definitions are then available in the template-implementation file when the function definition is compiled. Do not put the definitions of any classes used in template arguments in your source code. For each header file with template functions that need to be defined, the compiler generates a template-include file. The template-include file generates #include statements in that file for:  The header file with the template declaration  The corresponding template-implementation file  Any other header files that declare types used in template parameters. Before it invokes the linker, the compiler compiles the template-include files and generates the necessary template function definitions. Only one definition is generated for each template function. Use the same compiler options to link your object files that you use to compile them. For example, if you compile with the command: icc /C /Gm /Sa myfile.cpp link with the command: icc /Tdp /Gm /Sa myfile.obj This is especially important for options that control libraries, linkage, and code compatibility. This does not apply to options that affect only the creation of object code (for example, /C and /Fo). Note: By default, the compiler stores the template-include files in the TEMPINC subdirectory under the current directory. The compiler creates the TEMPINC directory if it does not already exist. To redirect the template-include files to another directory, use the /Ftdir compiler option, where dir is the directory to contain the template-include files. You can specify a fully-qualified path name or a path name relative to the current directory. If you specify a different directory for your template-include files, make sure that you specify it consistently for all compilations of your program, including the link step. Related Tasks:  How do I compile my programs Related Information:  The Using Templates section of the Programming Guide  The C++ Templates section of the Language Reference ═══ 33. Visually Create Program Parts ═══ Visual Builder is a visual programming tool that can help you create object-oriented programs using the C++ programming language. With Visual Builder, you can create applications faster and easier than you ever could using a text editor. Visual Builder provides a powerful visual editor, the Composition Editor, which enables you to create complete applications, often without writing code. You can start Visual Builder in the following ways:  From the C/C++ window  From the Tools folder  From a WorkFrame project environment Related Information:  The Visual Builder How Do I... information  The Visual Builder User's Guide  The Visual Builder Parts Reference ═══ Starting Visual Builder from the C/C++ Window ═══ To start Visual Builder from the C/C++ window, do the following: 1. Double-click on the icon for the VisualAge C++ desktop folder. 2. Double-click on the C/C++ Window icon. The C/C++ window opens. 3. Type the following: icsvb 4. Press the Enter key. A Visual Builder session is started. Related Information:  The Visual Builder How Do I... information  The Visual Builder User's Guide  The Visual Builder Parts Reference ═══ Starting Visual Builder from the Tools Folder ═══ To start Visual Builder from the Tools folder, do the following: 1. Double-click on the icon for the VisualAge C++ desktop folder. 2. Double-click on the Tools folder icon. 3. Double-click on the Visual Builder icon. A Visual Builder session is started. Related Information:  The Visual Builder How Do I... information  The Visual Builder User's Guide  The Visual Builder Parts Reference ═══ Starting Visual Builder from a WorkFrame Project ═══ You can start Visual Builder from a WorkFrame project environment in the following ways. Note: The following steps assume that your project inherits the settings of a WorkFrame project, or that you have changed the Visual action to the project level.  If the WorkFrame project environment is closed, you can click on the project icon with Mouse Button 2, and select Visual from the PopUp menu.  If the WorkFrame project environment is open, you can do either of the following: - Double-click on the name of the .VBB file. - Click on the name of the .VBB file with Mouse Button 2, and select Visual from the PopUp menu. - Click on the background in the project environment with Mouse Button 2, and select Visual from the PopUp menu. A Visual Builder session is started. If you used a .VBB file to open Visual Builder, that file is preloaded. Related Information:  The Visual Builder How Do I... information  The Visual Builder User's Guide  The Visual Builder Parts Reference ═══ 34. Work with DLLs ═══ You can do any of the following with runtime libraries (.DLLs):  Share a data segment from multiple DLLs  Export C++ members from a DLL  Ship a VisualAge C++ runtime library  Create your own DLLs  Choose runtime libraries  Link with .DLL files  Handle Signals and OS/2 Exceptions in DLLs Note: Note that this is not an exhaustive list. Related Information:  The Developing Subsystems section of the Programming Guide  The Packaging the VisualAge C++ Runtime DLLs ═══ 34.1. Sharing a data segment from multiple DLLs ═══ To share a data segment: 1. Use #pragma data_seg to name the data segment you want to share. 2. In the .DEF file for your DLL, specify DATA MULTIPLE NONSHARED. 3. In the .DEF file, add a SEGMENTS statement that specifies that the named segment is SINGLE SHARED. Note: If you need to initialize data structures in the shared segment, you will need to add this to the DLL initialization routine. Remember that this routine is run for each instance of your DLL, so you will need to ensure that your data structures are only initialized once. Related Information:  The Building DLLs section of the Programming Guide  The Creating Module Definition Files section of the User's Guide ═══ 34.2. Exporting C++ members from a DLL ═══ To export a member function from a DLL:  Specify the _Export keyword in either the class definition or the function definition. This keyword is not valid in the function prototype. For example, to export the function exportme from the class A: class A { void _Export exportme(); }; void _Export A::exportme() { return; } ═══ 34.3. Shipping a VisualAge C++ runtime library ═══ If you are shipping your application to other users, you must use one of three methods to make the VisualAge C++ runtime library functions available to the users of your application: 1. Statically bind every module to the library (.LIB) files. This method increases the size of your modules and also slows the performance because the library environment has to be initialized for each module. Having multiple library environments also makes signal handling, file I/O, and other operations more complicated. 2. Use the DLLRNAME to rename the VisualAge C++ library DLLs. You can then ship the renamed DLLs with your application. DLLRNAME is described in the Using the DLLRNAME Utility in the User's Guide. 3. Create your own runtime DLLs. This method provides one common runtime environment for your entire application. It also lets you apply changes to the runtime library without relinking your application, meaning that if the VisualAge C++ DLLs change, you only need to rebuild your own DLL. In addition, you can tailor your runtime DLL to contain only those functions you use, including your own. Note: DLLRNAME is a utility used to rename DLLs. It also alters the names in the compiled .EXE and .DLL files that use this renamed DLL. ═══ 34.4. Creating your own runtime libraries (DLLs) ═══ To create your own runtime library, follow these steps: 1. Copy and rename the appropriate VisualAge C++ .DEF file for the program you are creating. For example, for a multithread program, copy cppom30.def to myrtdll.def. You must also change the DLL name on the LIBRARY line of the .DEF file. The .DEF files are installed in the LIB subdirectory under the main VisualAge C++ installation directory. 2. Remove any functions that you do not use directly or indirectly (through other functions) from your .DEF file (myrtdll.def), file, including the STUB line. Do not delete anything with the comment **** next to it; variables and functions indicated by this comment are used by startup functions and are always required. 3. Create a source file for your DLL, for example, myrtdll.c. If you are creating a runtime library that contains only VisualAge C++ functions, create an empty source file. If you are adding your own functions to the library, put the code for them in this file. 4. Compile and link your DLL files. Use the /Ge- option to create a DLL, and the appropriate option for the type of DLL you are building (/Gm+ for multithread or /Gm-, the default, for single-thread). For example, to create a multithread DLL, use the command: icc /Ge- /Gm+ myrtdll.c myrtdll.def 5. Use the IMPLIB utility to create an import library for your DLL. For example: implib /NOI myrtdlli.lib myrtdll.def 6. Use the ILIB utility to convert the import library. For example: ilib /CONV /NOE /NOBR myrtdlli.lib 7. Use the ILIB utility to add the object modules that contain the initialization and termination functions to your import library. These objects are needed by all executable modules and DLLs. They are contained in cppom30o.lib for multithread programs and cppos30o.lib for single-thread programs. For information on how to use ILIB, see the Linking to a DLL Using an Import Library section of the User's Guide. Note: If you do not use the ILIB utility, you must ensure that all objects that access your runtime DLL are statically linked to the appropriate object library. 8. Compile your executable modules and other DLLs with the /Gn+ option to exclude the default library information. For example: icc /C /Gn+ /Ge+ myprog.c icc /C /Gn+ /Ge- mydll.c When you link your objects, specify your own import library. If you are using or plan to use OS/2 APIs, specify os2386.lib also. For example: ilink myprog.obj myrtdlli.lib os2386.lib ilink mydll.obj myrtdlli.lib os2386.lib To compile and link in one step, use the commands: icc /Gn+ /Ge+ myprog.c myrtdlli.lib os2386.lib icc /Gn+ /Ge- mydll.c myrtdlli.lib os2386.lib Note: If you did not use the ILIB utility to add the initialization and termination objects to your import library, specify the following when you link your modules: a. cppos30o.lib or cppom30o.lib b. Your import library c. os2386.lib (to allow you to use OS/2 APIs) d. The linker option /NOD. For example: ilink /NOD myprog.obj cppos30o.lib myrtdlli.lib os2386.lib; ilink /NOD mydll.obj cppos30o.lib myrtdlli.lib os2386.lib; The /NOD option tells the linker to disregard the default libraries specified in the object files and use only the libraries given on the command line. If you are using icc to invoke the linker for you, the commands would be: icc /B"/NOD" myprog.c cppos30o.lib myrtdlli.lib os2386.lib icc /Ge- /B"/NOD" mydll.c cppos30o.lib myrtdlli.lib os2386.lib The linker then links the objects from the object library directly into your executable module or DLL. ═══ 34.5. Choosing runtime libraries ═══ When you compile, the compiler defines default VisualAge C++ runtime libraries for the linker to use. You can use compiler options to control the linking process by changing the type of runtime library you link to. If you do not specify any options, the compiler uses the library that produces single-thread executable modules that are statically linked. You can link to another library by specifying the appropriate options. You would link to another library to:  Dynamically link your program  Create a multithread executable module.  Develop a subsystem.  Create a DLL for use with another executable module. The naming conventions used for the libraries are intended to help identify their function: C/C++ Runtime Libraries CPPpivvt.DLL CPPpivvt.LIB Where: p is the platform specifier  O for OS/2  W for Windows i is the library identifier  S for single-threaded  M for multi-threaded  n for no environment vv is the version number (major, minor, i.e. 3.0 = 30) t is the type  i for import library  o for object library (used for building imports)  blank for standard Open Class Libraries/Open Class Resource DLLs/Visual Builder Class Libraries/Data Access Builder Class Libraries/Performance Analyzer DLL/OBJ/Device Driver CPPpiivt.DLL CPPpiivt.LIB CPPpiivt.OBJ CPPpiivt.SYS Where: p is the platform specifier  O for OS/2  W for Windows ii is the library identifier  OB - Open Class Base library (Collection/Application Support)  OC - Open Class (for single import library)  OD - Open Class DDE library  OM - Open Class Multimedia library  OR - Open Class Resource DLLs  OU - Open Class User Interface Base library  OV - Open Class Visual library  OX - Open Class Complex library  OY - Open Class Complex Multithreaded library  Vn - Visual sample library n  DI - Data Access Builder IDL library  DS - Data Access Builder Static SQL library  PA - Performance Analyzer v is the version number  3 for IBM VisualAge C++ Version 3 t is the type  i for import library  o for object library (used for building imports)  blank for standard  U for US English (Resource DLL only)  J for Japanese (Resource DLL only)  K for Korean (Resource DLL only)  T for Taiwanese (Resource DLL only)  P for Simplified Chinese (Resource DLL only) Data Access Builder Resource DLLs CPPpSQvt.DLL Where: p is the platform specifier  O for OS/2  W for Windows v is the version number  3 for IBM VisualAge C++ Version 3 t is the type  U for US English (Resource DLL only)  J for Japanese (Resource DLL only)  K for Korean (Resource DLL only)  T for Taiwanese (Resource DLL only)  P for Simplified Chinese (Resource DLL only) ═══ 34.6. Linking with .DLL files ═══ ═══ 34.7. Handling signals and OS/2 exceptions in DLLs ═══ Handling signals and OS/2 exceptions in DLLs is no different than handling signals in executable files, providing all your DLLs and the executable files that use them are created using the VisualAge C++ compiler, and only one VisualAge C++ library environment exists for your entire application (your executable module and all DLLs). The library environment is a section of information associated with and statically linked to the VisualAge C++ library itself. You can be sure your program has only one library environment if:  It consists of a single executable module. By definition, a single module has only one copy of the VisualAge C++ library environment regardless of whether it links to the library statically or dynamically.  Your executable module dynamically links to a single DLL that is statically bound to the VisualAge C++ runtime library and that uses the VisualAge C++ library functions. The executable module then accesses the library functions through the DLL.  Your executable modules and DLLs all dynamically link to the VisualAge C++ runtime library. If more than one of your modules is statically linked to the VisualAge C++ library, your program has more than one library environment. Because there is no communication between these environments, certain operations and functions become restricted:  Stream I/O.  Memory allocation.  strtok, rand, and srand functions.  errno and _doserrno values.  Signal and OS/2 exception handlers. In general, it is easier to use only one library environment, but not always possible. For example, if you are building a DLL that will be called by a number of applications, you should assume that there may be multiple library environments and code your DLL accordingly. Related Information:  The Signal and OS/2 Exception Handling section of the Programming Guide ═══ 35. Work with Libraries ═══ The following topics are discussed in this How Do I... information:  Build/Maintain a .LIB  Link with .LIB files  Determine what classes are in the VisualAge C++ Open Class Library Note: Note that this is not an exhaustive list. Related Information:  How do I work with DLLs ═══ 35.1. Building/Maintaining a .LIB (object library) ═══ To build and maintain libraries of object code, use the ILIB utility. Library files are given the extension .LIB. ILIB works with standard libraries and OS/2 import libraries. It does not work with dynamic link libraries (DLLs). Use the ILIB utility to:  Create a new library  Add, delete, or replace modules in a library  Copy object modules in a library to object files  List the contents of a library Type ILIB at the OS/2 command prompt to start the utility. Parameters can be supplied by either specifying them directly on the command line, by responding to the prompts given by ILIB (use the /NOFREE option to get prompts), or by supplying a response file. The following prompts are given: Library Name Name of the input library to be modified or created. If the library you specify does not exist, you will be asked whether to create a new one. Operation(s) Commands to modify the library. If no operations are specified, the input library is unchanged. List File Name of the listing file to be created. If no listing file is specified, then no listing file is created. New Library Name Name of the output library to be created from the input library. If no output library is specified, the ILIB will modify the input library. For more information on using the ILIB utility, see the ILIB Commands section of the User's Guide. ═══ 35.2. Linking with .LIB files ═══ ═══ 35.3. Determining what classes are in the VisualAge C++ Open Class Library ═══ ═══ If You Still Need Help ═══ If you did not find the answer to your question in this information, please try one of the following:  How Do I... information for each component of VisualAge C++: - Browser - Data Access Builder - Debugger - Editor - Performance Analyzer - Visual Builder - WorkFrame  Frequently Asked Questions  User's Guide information for conceptual information using the components of VisualAge C++ and the classes of the VisualAge C++ Open Class Library for coding in C and C++: - Browser - Class Library - Data Access Builder - Debugger - Editor - Open Class Library - Performance Analyzer - Visual Builder - WorkFrame  Programming Guide  Reference information for coding in C and C++: - C Library Reference - Editor Command Reference - Language Reference - Open Class Library Reference - Visual Builder Parts Reference If you still require assistance, see How Do I Get Support. This covers telephone and electronic support for US, Canada and outside North America. In addition, it outlines how to acquire your free 60-day getting started period.