Shared library concept

Source: Internet
Author: User

Generally, databases are divided into static databases, shared libraries, and Dynamically Loaded libraries ,. The following sections describe each other.
I. Static Library:
1. concept:
A static library is a set of target files ending with.. The static library is used when the program is linked. The linker uses
The code to the function is copied from the library file to the application. Once the link is complete, no static library is required for executing the program.
Because every application using a static library needs to copy the code of the function used, the static link file will be large.
2. Creation and application:
First create the library file libhello. c
# Include
Void Hello ()
{
Printf ("Hello, welcome to library world! \ N ");
}
Create the header file libhello. h
Void Hello ();
Now we create the libhello static library file:
$ Gcc-C libhello-O libhello. o
$ Ar RCS libhello. A libhello. o
Here, what is the meaning of the RCS in AR: R indicates that the module is added to the static database, C indicates that the static database is created, and s indicates that the production index is created.

Let's write a test program:
$ CAT test. c
# Include
Int main (void)
{
Printf ("use library hello. \ n ");
Hello ();
Return 0;
}

Compilation and link:
$ Gcc-C test. C-O test. o
$ GCC test. O-L.-lhello-o Test
Description:-L. adds the current directory to the library search path. The default library search path is in the/usr/lib directory.
In addition, here we will describe the confusing parameter-I, which indicates the path of the header file to be searched. In this way, GCC first searches for the header file in the directory specified by-I, and then the default directory of the system.

-L parameter:-lname indicates the libname. A or libname. So file in the library search directory. This is one of the reasons why library files start with Lib. A convention. Of course, if your library file is not libhello, but hello. You cannot compile it with the-l parameter. You can do this:
GCC test. O-L. Hello. A-o Test

Note: $ gcc-L.-lhello test. O-O test will cause an error !.
The reason is:-L is the linker option and must be placed behind the compiled file. Therefore, the above command-lhello must be placed behind test. O.
Run:
$./Test
Use library hello.
Hello, welcome to library world!

Ii. Shared libraries:
1. Concepts of shared libraries:
The shared library ends with. So. (So = Share Object). When linking a program, it does not copy the code that uses the function as the static library, but just makes some marks. Then, when the program starts running, it dynamically loads the required modules. Therefore, applications still need the support of shared libraries when running. The files linked to the shared library are much smaller than those linked to the static library.
2. Name the Shared Library
Generally, a shared library has three names: soname, real-name, and linker-name. Let's take a look at the instance first:
$ LS-L/usr/lib/libncurses *
Lrwxrwxrwx 1 Root 20 2008-05-25 13:54 libncurses. So->/lib/libncurses. so.5
Lrwxrwxrwx 1 Root 13 2008-05-26 :18 libncurses. so.5-> libtermcap. So
The above libncurses. so.5 is the soname, where ncurses is the database name, and 5 is the main version number (Major ),
Of course, there can also be a version number (minor) and a release number (release ). (Similar to ibncurses. so.5.0.0)
. So, of course, indicates the shared library. Generally, soname is only a link of real name.
While libtermcap. So is the real-name of the ncurse library, that is, the file that contains the real code implementation. libncurses. So is the linkername, which is a search name used for application link. It is usually a link of soname, in the form of libname. So
In fact, each database has a soname. When the connector finds that the library It is searching for has such a name, the connector will embed the soname into the binary file in the link, instead of the actual file name it is running, during program execution, the program will find the file with the soname name, rather than the file name of the library. In other words, soname is the identification mark of the library.

The main purpose of this operation is to allow the coexistence of database files of multiple versions in the system. Normally, the name library file is the same as the soname file.
3. Shared Library Loading
(1) In all gnuglibc-based systems (including Linux, of course), when an elf binary execution program is started,
A special program "program loader" will be automatically loaded and run. In Linux, the program loader is
/Lib/ld-linux.so.X (X is the version number ). It searches for and loads all the shared libraries on which the application depends.
The directory to be searched is stored in the/etc/LS. So. conf file, but generally/usr/local/lib is not in the search column, at least Debian/Ubuntu is like this. This seems to be a system error, so I had to add it myself. Of course, if a program is searched every time it is started, the efficiency will inevitably be unbearable. This has been taken into account in Linux and Cache Management has been adopted for shared libraries. Ldconfig is a tool for implementing this function. It reads/etc/LD by default. so. CONF file to establish symbolic connections for all shared libraries according to certain specifications, and then write the information to/etc/lD. so. cache.
The existence of/etc/lD. So. cache greatly accelerates program startup.
(2) Of course, you can also set the LD loading path by setting the environment variable LD_LIBRARY_PATH. In this way, the loader will first search for the Directory of the variable, and then the default directory. But remember, LD_LIBRARY_PATH is used for development and testing. You can put some directories used for testing to replace shared libraries into this variable, which is similar to/etc/lD. So. preload. However, this variable should not be used in normal programs of normal users.
(3) If you do not use the LD_LIBRARY_PATH environment variable, you can pass the path to the loader as follows:
$/Lib/ld-linux.so.2 -- library-Path executable

 

(4) creating shared libraries and linking executable files is similar: first compile the source code into the target file, and then link the target file. the target file needs to be created as a position-independent code (PIC). The concept is that when executable programs load them, they can be stored anywhere in the memory of the executable program (the target file for the executable file is not usually compiled in this way .) commands linked to a dynamic library contain special symbols, which are different from commands linked to executable files.

 

In the following example, we assume that your source code is in Foo. file C and create it as Foo. so shared library. the object file of the intermediary is called foo. o unless otherwise specified. A shared library can contain multiple object files, but we only use one.

BSD/OS

The compiler flag for creating the PIC is-FPIC. The connector flag for creating the shared library is-shared.

Gcc-FPIC-C Foo. c

LD-shared-O Foo. So Foo. o

The above method applies to version 4.0 BSD/OS.

FreeBSD

The compiler flag for creating the PIC is-FPIC. The connector flag for creating the shared library is-shared.

Gcc-FPIC-C Foo. c

Gcc-shared-O Foo. So Foo. o

The above method applies to FreeBSD of version 3.0.

HP-UX

The system compiler flag for creating the PIC is + Z. If GCC is used, it is-FPIC. The linker flag for creating the shared library is-B. Therefore

CC + Z-C Foo. c

Or

Gcc-FPIC-C Foo. c

Then

LD-B-o Foo. SL Foo. o

HP-UX uses. SL for shared library extension, unlike most other systems.

IRIX

PIC is the default and no special compiler options are required. The linker option for generating the shared library is-shared.

CC-C Foo. c

LD-shared-O Foo. So Foo. o

Linux

The compiler flag for creating PIC is-FPIC. in some environments on some platforms, if-FPIC cannot be used, you must use-FPIC. refer to the GCC manual for more information. the compiler flag for creating a shared library is-shared. A complete example looks like:

CC-FPIC-C Foo. c

CC-shared-O Foo. So Foo. o

NetBSD

The compiler flag for creating the PIC is-FPIC. For the elf system, the compilation command with the-shared flag is used to link the shared library. In the old non-elf system, use LD-bcyclable.

Gcc-FPIC-C Foo. c

Gcc-shared-O Foo. So Foo. o

OpenBSD

The compiler flag for creating the PIC is-FPIC. LD-bshareable, which is used to link the shared library.

Gcc-FPIC-C Foo. c

LD-bshareable-O Foo. So Foo. o

Solaris

The compiler command for creating a pic is to use-FPIC when GCC is used for-KPIC when sun compiler is used. When the shared library is linked, both compilers can use-G or-shared when GCC is used.

CC-g-KPIC-O Foo. So-C Foo. c

Or

Gcc-FPIC-C Foo. c

Gcc-g-o Foo. So Foo. o

Tru64 UNIX

PIC is the default, so the compilation command is the common one. LD with special options is used for linking:

CC-C Foo. c

LD-shared-expect_unresolved '*'-O Foo. sofoo. o

The process of replacing the system compiler with GCC is the same; special options are not required.

Unixware

The SCO compiler creates an image. It indicates that-kpic gcc is-FPIC. When the shared library is linked, the SCO compiler uses-G and GCC uses-shared.

CC-K pic-C Foo. c

CC-g-o Foo. So Foo. o

Or

Gcc-FPIC-C Foo. c

Gcc-shared-O Foo. So Foo. o
4. create and apply a shared library
(1) create a shared library:
Gcc-FPIC/FPIC-C source. C-o Source. o
Gcc-shared-wl,-soname, your_soname-O library_name file_list library_list
Note:-FPIC or-FPIC indicates creating positionindependent code, which is usually required to create a shared library.
-Wl indicates that parameters are transmitted to the linker.-soname and library_name are parameters sent to the linker.
-Shared indicates that the shared library is used.
The following is an example of using A.C and B .C to create a shared library:
Gcc-FPIC-g-C-wall a. c
Gcc-FPIC-g-C-wall B. C
Gcc-shared-wl,-soname, libmyab. so.1-O libmyab. so.1.0.1 A. o B. O-lC
Note: lc = libc

Notes:
A. It is not recommended to use strip to process shared libraries. It is best not to use the-fomit-frame-pointer compilation option.
B. Both-FPIC and-FPIC can generate independent code of the target. The specific application depends on the platform.-FPIC is always work,
Although the target file may be larger, the code generated by FPIC is small and the execution speed is fast, there may be restrictions on platform dependencies.
C. In general, the-wall,-soname, and your_soname compilation options are required. Of course, the-share option cannot be lost.
(2) install and use a shared library
Once you have created a shared library, you need to install and use it. The simplest way is to copy the Library to the default directory (/usr/lib ).
Then create some symbolic links. The simplest way is to use ldconfig (8) to process the symbolic links here. The last is re-
Compile your program and specify the library path through the-L and-l parameters.
Iii. Dynamic Library Loading
1. Concept
Dynamicallyloaded (DL) libraries is a function library that can be loaded while the program is running. Instead of loading a program at startup like a shared library. DL is very useful for implementing plug-ins and modules because it allows programs to wait for the plug-in to load when allowed. In Linux, the file format of the dynamic library is no different from that of the shared library. The main difference is that the shared library is loaded at runtime.
A dedicated set of APIs are provided to enable dynamic libraries, search for symbols, handle errors, and disable dynamic libraries.

The following describes these interface functions one by one:
(1) dlopen
Function prototype: void * dlopen (const char * libname, int flag );
Function Description: dlopen must be called before dlerror, dlsym, and dlclose to load the database to the memory.
If the library to be loaded depends on other libraries, you must first load the dependent library. If the dlopen operation fails, the return value is null. If the database has been loaded, the dlopen returns the same handle.
The libname In the parameter is generally the full path of the library, so that the dlopen will directly load the file; if only the library name is specified, the dlopen will follow the mechanism below to search:
A. Search by environment variable LD_LIBRARY_PATH
B. Search by/etc/lD. So. Cache
C. Search in the/lib and/usr/lib directories in sequence.
The flag parameter indicates the way to process undefined functions. You can use rtld_lazy or rtld_now. Rtld_lazy indicates that the undefined function is not processed for the time being. First, the Library is loaded to the memory and the undefined function is used. rtld_now indicates that the undefined function is checked immediately. If so, then, dlopen ends with a failure.
(2) dlerror
Function prototype: char * dlerror (void );
Function Description: dlerror can be used to obtain the error message of the last dlopen, dlsym, or dlclose operation. If null is returned, no error is returned. When an error message is returned, dlerror also clears the error message.
(3) dlsym
Function prototype: void * dlsym (void * handle, const char * symbol );
Function Description: The database is loaded to the memory after the dlopen. Dlsym can obtain the position (pointer) of the specified function in the memory ).
If the specified function cannot be found, dlsym returns NULL. However, the best way to determine whether a function exists is to use the dlerror function,
(4) dlclose
Function prototype: intdlclose (void *);
Function Description: Delete the loaded library handle by one. If the handle is reduced to zero, the database will be uninstalled. If a destructor exists, after dlclose, The Destructor will be called.

2. Use instances
$ Cat dltest. c
# Include
# Include
# Include
Int main (INT argc, char ** argv)
{
Void * handle;
Double (* cosine) (double );
Char * error;
Handle = dlopen ("/lib/libm. so.6", rtld_lazy );
If (! Handle ){
Fputs (dlerror (), stderr );
Exit (1 );
}
Cosine = dlsym (handle, "Cos ");
If (error = dlerror ())! = NULL ){
Fputs (error, stderr );
Exit (1 );
}
Printf ("% F \ n", (* cosine) (2.0 ));
Dlclose (handle );
Return 0;
}

Compile: $ gcc-odltest dltest. C-LDL-wall
Run: $./dltest
-0.416147
IV,View symbols in the library
(1) The nm command can check symbols in a library.
There are many symbols listed in nm, and there are three common ones. One is called in the library but not defined in the Library (indicating that it needs to be supported by other libraries), which is displayed in the utable; one is the function defined in the library, represented by T, which is the most common; the other is the so-called "weak state" symbol, although they are defined in the library, however, it may be overwritten by symbols of the same name in other databases, represented by W. For example, if the developer wants to know whether printf () is defined in the hello Library mentioned above ():

$ Nm libhello. So | grep printf
U printf
The u table symbol printf is referenced, but is not defined in the function. It can be inferred that to use the hello library normally, it must be supported by other libraries, run the LDD command to check which libraries Hello depends on:
$ LDD hello
Libc. so.6 =>/lib/libc. so.6 (0x400la000)
/Lib/ld-linux.so.2 =>/lib/ld-linux.so.2 (0x40000000)
From the above results, we can continue to check where printf is defined.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.