|FreeTDS User Guide: A Guide to Installing, Configuring, and Running FreeTDS|
|Prev||Appendix A. On Linkers||Next|
A C library is a set of named functions, for example dbinit() or SQLConnect(). Or, for that matter, fopen(3).
Libraries come in two flavors: static and dynamic.
Static libraries (also known as archives) have been around as long as C itself. Like a .zip file, they're just a bag of object files — containing functions, of course — with a table of contents in front giving the address of each name. Static libraries are created from object files using a librarian utility of some kind. One such programs is ar, for archive.
Static libraries are part of the build environment. Functions in static libraries are joined to a program's main module by a static linker at build time to produce an executable program. The executable incorporates the libraries' object code into its own body, making it completely self-sufficient.
Dynamic libraries are the new kid on the block, as these things go, arriving on the Unix scene circa 1985. Like a static library, a dynamic library is a collection of functions with a table of contents. They are referenced at build time to give the executatble information about how they will eventually be used, but they aren't used until run time.
Dynamic libraries are part of the run-time environment. When a program is run, the run-time linker finds the dynamic libraries needed by the program, finds the addresses of the required functions, and assembles a runable image in memory. Missing libraries and/or missing functions — or the wrong versions of them — can lead to head-scratching and other amusing behavior.
In Windows® dynamic libraries are called dynamic link libraries (DLLs). In Unix they're normally called shared objects. But they're roughly the same thing.
|What about .h files?|
C header files include functional prototypes, declarations (not definitions) of functions. Functional prototypes describe to the compiler each function's parameters, allowing the compiler to confirm that the function is being called correctly.
Most of the functions declared in header files are implemented in libraries. However, there's no mechanical or automatic relationship between the functional prototypes in the header files and their implementation in a library. The .h file is maintained by hand, by the programmer, and is used to generate a library. The header file and associated library are distributed and installed together (one hopes), but correct installation and subsequent use by the compiler & linker require human beings to keep track of the pair. Failure to do so leads to "interesting" development and even run-time problems, especially with libraries whose functions' parameters change from version to version.
For example, imagine a function f(int g) defined in library libf.so and declared in f.h. In a later version of libf.so, the function's parameter is changed to use a pointer, f(int *p), and f.h is likewise updated. Possible errors that cannot be prevented by the linker include:
The Unix convention is to put in parentheses behind the name the section of the manual in which the function is documented. FreeTDS functions don't get numbers because they're not in the manual. Yet.
Or, depending on how you look at it, the name of each address.