Library Functions

Programs of any complexity make use of functions. A function is a collection of declarations and statements that carries out a specific action and/or returns a value. Functions are either defined by the user or have been previously defined and made available to the user . Previously defined functions that have related functionality or are commonly used (e.g., math or graphics routines) are stored in object code format in library (archive) files . Object code format is a special file format that is generated as an intermediate step when an executable program is produced. Like executable files, object code files are also not displayed to the screen or printed. Functions stored in library files are often called library functions or runtime library routines .

The standard location for library files in most UNIX systems is the directory /usr/lib . Ancillary library files may also be found in the /usr/local/lib directory. Two basic types of libraries are used in compilationsstatic libraries and shared object libraries. Static libraries are collections of object files that are used during the linking phase of a program. Referenced code is extracted from the library and incorporated in the executable image. Shared libraries contain relocatable objects that can be shared by more than one application. During compilation the object code from the library is not incorporated in the executable code only a reference to the object is made. When the executable that uses a shared object library is loaded into memory the appropriate shared object library is loaded and attached to the image. If the shared object library is already in memory this copy is referenced. As might be expected shared object libraries are more complex than static libraries. In Linux, by default, shared object libraries are used if present otherwise static libraries are used. Most, but not all, compiler installations include both types of libraries. In the examples below we will focus on the more ubiquitous static libraries.

By convention, the three-letter prefix for a library file is lib and the file extension for a static library is .a . The UNIX archive utility ar , which creates, modifies, and extracts members from an archive, can be used to examine library file contents. [1] For example, the command

[1] The archive utility is one of the many exceptions to the rule that all command-line options for system utilities begin with a hyphen (-).

linux$ ar t /usr/lib/libc.a pr -4 -t

will pipe the table of contents (indicated by the t command-line option) of the standard C library file ( libc.a ) to the pr utility, which will display the output to the screen in a four-column format. The object code in this library is combined by default with all C programs when they are compiled. Therefore, in a C program when a reference is made to printf , the object code for the printf function is obtained from the /usr/lib/libc.a library file. Similarly, the command

linux$ ar t /usr/lib/libstdc++-3-libc6.2-2-2.10.0.a pr -4 -t

will display the table of contents of the C++ library file used by the gcc compiler. Remember that the versions (and thus the names ) of library files can change when the compiler is updated.

Additional information can be extracted from library files using the nm utility. For example, the command

linux$ nm -C /usr/lib/libstdc++-3-libc6.2-2-2.10.0.a grep 'bool operator=='

will find all the C++ equality operators in the referenced library file. The -C command-line option for nm demangles the compiler-generated C++ function names and makes them a bit more readable.

The ar command can also be used to create a library. For example, say we have two functions. The first function, called ascii , is stored in a file called ascii.cxx . This function generates and returns an ASCII string when passed the starting and endpoint for the string. The second function, called change_case (stored in the file change_case.cxx ), accepts a string and inverts the case of all alphabetic characters in the string. The listing for the two programs is shown in Figure 1.1.

Figure 1.1 Source code for two functions to be stored in archive libmy_demo.a .

File : ascii.cxx char * ascii( int start, int finish ){ char *b = new char(finish-start+1); for (int i=start; i <= finish; ++i) + b[i-start]=char( i ); return b; } ____________________________________________________________________________________ File : change_case.cxx #include char * change_case( char *s ){ + char *t = &s[0]; while ( *t ){ if ( isalpha(*t) ) *t += islower(*t) ? -32 : 32; ++t; 10 } return s; }

Each file is compiled into object code, the archive libmy_demo.a generated, and the object code added to the archive with the following command sequence:

linux$ g++ -c change_case.cxx linux$ g++ -c ascii.cxx linux$ ar cr libmy_demo.a ascii.o change_case.o

The prototypes for the functions in the my_demo library are placed in a corresponding header file called my_demo.h . Preprocessor directives are used in this file to prevent it from being inadvertently included more than once. A small C++ program, main.cxx , is created to exercise the functions. With the "" notation for the include statement in main.cxx , the compiler will look for the my_demo.h header file in the current directory. The contents of the my_demo.h header file and the main.cxx program are shown in Figure 1.2.

Figure 1.2 Header file and test program for libmy_demo.a .

File : my_demo.h /* Prototypes for my_demo library functions */ #ifndef MY_DEMO_H + #define MY_DEMO_H char * ascii( int, int ); char * change_case( char * ); 10 #endif ____________________________________________________________________________________ File : main.cxx #include #include "my_demo.h" using namespace std; int + main( ) { int start, stop; char b[20]; // temp string buffer cout << "Enter start and stop value for string: "; 10 cin >> start >> stop; cout << "Created string : " << ascii(start, stop) << endl; cin.ignore(80,' '); cout << "Enter a string : "; cin.getline(b,20); + cout << "Converted string: " << change_case( b ) << endl; return 0; }

The compilation shown below uses the -L command-line option to indicate that when the compiler searches for library files it should also include the current directory. The name of the library is passed using the -l command-line option. As source files are processed sequentially by the compiler, it is usually best to put linker options at the end of the command sequence to avoid the generation of any undefined reference errors.

linux$ g++ -o main main.cxx -L. -lmy_demo

A sample run of the main.cxx program is shown in Figure 1.3.

Figure 1.3 Sample run testing the archived functions.

linux$ main <-- 1 Enter start and stop value for string: 56 68 Created string : 89:;<=>?@ABCD Enter a string : This is a TEST! Converted string: tHIS IS A test!

(1) If your distribution of Linux does not include "." as part of its login path you will need to invoke the program as ./main .

If your system supports the apropos command, you may issue the following command to obtain a single-line synopsis of the entire set of predefined library function calls described in the manual pages on your system:

linux$ apropos '(3'

As shown, this command will search a set of system database files containing a brief description of system commands returning those that contain the argument passed. In this case, the ' (3 ' indicates all commands in Section 3 of the manual should be displayed. Section 3 (with its several subsections) contains the subroutine and library function manual pages. The single quotes are used in the command sequence so the shell will pass the parenthesis on to the apropos command. Without this, the shell would attempt to interpret the parenthesis, which would then produce a syntax error.

Another handy utility that searches the same database used by the apropos command is the whatis command. The command

linux$ whatis exit

would produce a single-line listing of all manual entries for exit . If the database for these commands is not present, the command /usr/ sbin/makewhatis , providing you have the proper access privileges, will generate it.

A more expansive overview of the library functions may be obtained by viewing the intro manual page entry for Section 3. On most systems the command

linux$ man 3 intro

will return the contents of the intro manual page. In this invocation the 3 is used to notify man of the appropriate section. For some versions of the man command, the option -s3 would be needed to indicate Section 3 of the manual. Additional manual page information addressing manual page organization and use can be found in Appendix A, "Using Linux Manual Pages."

In addition to manual pages, most GNU/Linux systems come with a handy utility program called info . This utility displays documentation written in Info format as well as standard manual page documents. The information displayed is text-based and menu-driven . Info documents can support limited hypertext-like links that will bring the viewer to a related document when selected. When present, Info documentation is sometimes more complete than the related manual page. A few of the more interesting Info documents are listed in Table 1.1.

Table 1.1. Partial Listing of Info Documents.

Topic

Description

as

The GNU assembler.

binutils

GNU binary utilities (such as ar ).

fileutils

GNU file manipulation utilities.

gcc

The gcc (and g++ ) compiler. Look here for information on how to use the compiler, special C++ extensions, etc.

gdb

How to use the GNU symbolic debugger.

info

How to use the info system. Look here for all the gory details on how to use info and write Info type documentation.

ipc

System V style interprocess communication constructs: message queues, semaphores, and shared memory.

libc

The C library (as implemented by GNU). A good place to start for an overview on topics such as signals, pipes, sockets, and threads.

The info utility should be invoked on the command line and passed the item (a general topic or a specific commandsystem call, library function, etc.) to be looked up. If an Info document exists, it is displayed by the info utility. If no Info document exists but there is a manual page for the item, then it is displayed (at the top of the Info display will be the string *manpages* to notify you of the source of the information. If neither an Info document nor a manual page can be found, then info places the user in the info utility at the topmost level. When in the info utility, use the letter q to quit or a ? to have info list the commands it knows . Entering the letter h will direct info to display a primer on how to use the utility.

Категории