|
|
HP C++ Programmer's Guide: HP 9000 Series Workstations and Servers > Chapter 3 Compiling and Executing HP C++ ProgramsCreating and Using Shared Libraries |
|
This section provides information about shared libraries that is specific to HP C++. For additional information about creating and using shared libraries, see the manual HP-UX Linker and Libraries Online User Guide. For information on using the options to the CC command, see Table 3-1 “The CC Command Options” in this chapter. To create a C++ shared library, you must first compile your C++ source with either the +z or +Z option. These options create object files containing position-independent code (PIC). To create a shared library from one or more object files, use the -b option at link time. (The object files must have been compiled with +z or +Z.) The -b option creates a shared library rather than an executable file. To use a shared library, you simply include the name of the library on the CC command line as you would with an archive library, or use the -l option, as with other libraries. The linker links the shared library to the executable file it creates. Once you create an executable file that uses a shared library, you must not move the shared library or the dynamic loader (dld.sl(5)) will not be able to find it. The following command compiles the two files Strings.C and Arrays.C and creates the two object files Strings.o and Arrays.o. These object files contain position-independent code (PIC):
The following command builds a shared library named libshape.sl from the object files Strings.o and Arrays.o:
The following command compiles a program, draw_shapes.C, that uses the shared library, libshape.sl:
If both an archive and shared version of a particular library reside in the same directory, the linker links in the shared version by default. You can override this behavior with the -a linker option. This option tells the linker which type of library to use. The -a option is positional and applies to all subsequent libraries specified with the -l option until the end of the command line or until the next -a option is encountered. The syntax of this option when used with CC is: -Wl,-a [archive ] [shared ] [default] The different meanings of this option are:
The following example directs the linker to use the archive version of the library libshape, followed by standard shared libraries if they exist; otherwise select archive versions.
The CC command cannot replace or delete object modules in a shared library. To update a C++ shared library, you must recreate the library with all the object files you want the library to include. If, for example, a module in an existing shared library requires a fix, simply recompile the fixed module with the +z or +Z option, then recreate the shared library with the -b option. Any programs that use this library will now be using the new versions of the routines. That is, you do not have to relink any programs that use this shared library because they are attached at run time. By default, the linker exports from a program only those symbols that were imported by a shared library. For example, if an executable's shared libraries do not reference the program's main routine, the linker does not include the main symbol in the a.out file's export list. Normally, this is a problem only when a program explicitly calls shared library management routines. (See "Routines You Can Use to Manage C++ Shared Libraries" later in this chapter.) To make the linker export all symbols from a program, use the -Wl,-E option which passes the -E option to the linker. Because shared library routines and data are not actually contained in the a.out file, the dynamic loader must attach the routines and data to the program at run time. To accelerate program startup time, routines in a shared library are not bound until referenced. (Data items are always bound at program startup.) This deferred binding distributes the overhead of binding across the total execution time of the program and is especially helpful for programs that contain many references that are not likely to be executed. You can force immediate binding, which forces all routines and data to be bound at startup time. With immediate binding, the overhead of binding occurs only at program startup time, rather than across the program's execution. Immediate binding also detects unresolved symbols at startup time, rather than during program execution. Another use of immediate binding is to get better interactive performance, if you don't mind program startup taking longer. To force immediate binding, use the option -Wl,-B,immediate. For example,
To get the default binding, use -Wl,B,deferred. For more information, see HP-UX Linker and Libraries Online User Guide. When you use C++ shared libraries, all constructors and destructors of nonlocal static objects in the library execute. This is different from C++ archive libraries where only the constructors and destructors in object files you actually use are executed. You can call any of several routines to explicitly load and unload shared libraries, and get information about shared libraries. Refer to HP-UX Linker and Libraries Online User Guide for information about these routines. HP C++ provides the following additional routines for managing C++ shared libraries:
When you use either of these routines, be sure to compile with the -ldld option to link them in. The C++ shared library management routines (cxxshl_load() and cxxshl_unload()) use special data types and constants defined in the header file /usr/include/CC/cxxdl.h (/opt/CC/include/cxxdl.h for HP-UX 10.x C++ versions). When using these functions from a C++ program be sure to include cxxdl.h:
If an error occurs when calling shared library management routines, the system error variable, errno, is set to an appropriate error value. Constants are defined for these error values in /usr/include/errno.h (see errno(2)). Thus, if a program checks for these values, it must include errno.h:
You can create different versions of a routine in a shared library with the HP_SHLIB_VERSION pragma. HP_SHLIB_VERSION assigns a version number to a module in a shared library. The version number applies to all global symbols defined in the module's source file. The syntax of this pragma is:
The date argument is of the form month/year. The month must be 1 through 12, corresponding to January through December. The year can be specified as either the last two digits of the year (92 for 1992) or a full year specification (1992). Two-digit year codes from 00 through 40 represent the years 2000 through 2040. This pragma should only be used if incompatible changes are made to a source file. If a version number pragma is not present in a source file, the version number of all symbols defined in the object module defaults to 1/90. For more information about version control in shared libraries, see HP-UX Linker and Libraries Online User Guide. To rebuild a shared library with new versions of some of the object files, use the CC command and the -b option with the old object files and the newly compiled object files. The new source files should use the HP_SHLIB_VERSION pragma. For example, suppose the source file box.C has been compiled into the shared library libshape.sl. Further suppose you want to add new functionality to functions in box.C, making them incompatible with existing programs that call libshape.sl. Before making the changes, make a copy of the existing box.C and name it oldbox.C. Then change the routines in box.C, using the version pragma specifying the current month and year. The following illustrates these steps:
To update the shared library, libshape.sl, to include the new box.C routines, compile box.C and rebuild the library with the new box.o and oldbox.o:
Thereafter, any programs linked with libshape.sl use the new versions of the box.C routines. Programs linked with the old version still use the old versions. |
|