Linux library knowledge-general Linux technology-Linux programming and kernel information. The following is a detailed description. Introduction:
In xmeeting, for the usb handle, the dynamic library call method is used. Next I will translate an article written by David A. Wheeler. This article discusses how to create and use static databases, share libraries, and dynamically load libraries. The content is as follows:
1. Overview
2. Static Library
3. Shared Library
3.1 conventions
3.2 use
3.3 Environment Variables
3.4 create a shared library
3.5 Installation and Use
3.6 compatibility
4. Dynamic Loading
4.1 dlopen ()
4.2 dlerror ()
4.3 dlsym ()
4.4 dlclose ()
4.5 example
5. Auxiliary knowledge
5.1 nm command
5.2 database construction and destructor
5.3 script
Version 5.4
5.5 GNU libtool
5.6 remove symbol Space
5.7 external execution body
5.8 C ++ and C
5.9 accelerate C ++ Initialization
5.10 Linux standards
1. Overview
This article discusses how to use the GNU tool in Linux to create and use libraries. The so-called "library" is simply a file that contains data and Execution Code. It cannot be executed independently and can be used as part of other execution programs to complete the execution function. Library can make the program modular, accelerate the re-Compilation of the program, realize code reuse, and make the program easy to upgrade. Library can be divided into three types: static library, shared library and Dynamic Load Library.
The static library is added to the Execution Code before the execution program runs and physically becomes a part of the execution program. The shared library is loaded into the execution program when the execution program starts, it can be shared by multiple execution programs. Dynamic library loading is not a real library type. It should be a library Usage Technology, and applications can load and use libraries at any time during the running process.
It is recommended that library developers create shared libraries. The obvious advantage is that the libraries are independent for easy maintenance and updates. Static library updates are troublesome and generally not recommended. However, they have their own advantages, which will be discussed later. In C ++ programming, to use dynamic loading technology, refer to the article "C ++ dlopen MINI-Howto ".
The execution programs and libraries described in this article use the ELF (Executable and Linking Format) Format. Although the gnu gcc tool can process other formats, it is not covered in this article. This article can be found at http://www.dwheeler.com/program-libraryand http://www.linuxdoc.org.
2. Static Library
Static libraries can be considered as a collection of target code. According to habits, ". a" is generally used as the file suffix. You can use the ar (archiver) command to create a static library. Because shared libraries have a greater advantage, static libraries are no longer frequently used. However, static databases are easy to use and still have room for use.
The static library does not need to be compiled when the application is generated, saving the Compilation Time. But as the compiler is getting faster and faster today, this does not seem important. If other developers want to use your code and you do not want to provide the source code, it is an option to provide a static library. Theoretically, applications use static databases, which is 1-5% faster than dynamic databases. However, this may not be the case for some inexplicable reasons. From this point of view, in addition to ease of use, static databases may not be a good choice.
To create a static library or add the target code to an existing static library, run the following command:
Ar rcs my_libraty.a file1.o file2.o
The above indicates that the target code file1.o and file2.o should be added to the static library my_library.a. If my_library.a does not exist, it is automatically created.
After the static library is created, you need to connect to the application for use. If you use gcc (1) to generate the execution program, you must use the-l option to specify the static library. For more information, see the gcc user manual.
Pay attention to the order of parameters when using gcc. -L is the connector option. It must be placed after the name of the compiled file. If it is placed before the file name, the connection will fail and an inexplicable error will occur. This is important.
You can also directly use the connector ld (1) and use its option-l or-L. However, it is best to use gcc (1) because the ld (1) interface may change.
3. Shared Library
Shared libraries are loaded when the program starts. When an application loads a shared library, other applications can still load the same shared library. Based on the usage of linux, the shared library has other flexible and exquisite features:
Updating the database does not affect the use of the old and Incompatible version of the application;
When executing a specific program, it can overwrite a specific function in the entire library or update the library;
The above operations will not affect the running programs, and they will still use the loaded libraries.
3.1 conventions
To share a library with the above features, some conventions need to be observed. You need to know the differences between shared library names, especially the differences and relationships between soname and realname. You also need to know the location of shared library in the file system.
3.1.1 name
Each shared database has a specific search name (soname), which is composed of the following:
Lib + Library name +. so +. + version
| _______________ |
Prefix database name suffix
In the file system, the search name is a symbolic link pointing to the real name.
Each Shared Library also has a real name, which actually contains the code of the library, which is composed of the following:
Search +. + sub-version number +. + release number
The last period and release number are optional.
In addition, the shared library also has a name, which is generally used to compile the connection, called the linker name. It can be seen as a search name without any version number.
See the following example:
Lrwxrwxrwx 1 root libpng. so-> libpng12.so
Lrwxrwxrwx 1 root libpng. so.2-> libpng. so.2.1.0.12
-Rw-r -- 1 root libpng. so.2.1.0.12
In the above information, libpng. so.2.1.0.12 is the real name (libpng) of the shared library. so.2 is the shared library search name (soname), libpng. so is the connection name (linker name), used to compile the connection.
3.2 load shared libraries
In all GNU glibc-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, this 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 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.
3.3 create a shared library
Creating a shared library is simple and involves two steps. First, use-fPIC or-fpic to create the target file. PIC or pic indicates the location-independent code. Then you can create a shared library in the following format:
Gcc-share _ Wl,-soname, your_soname-o library_name file_list library_list
The following is an example of using A.C and B .C to create a database:
Gcc-fPIC-g-c-Wall a. c
Gcc-fPIC-g-c-Wall B. c
Gcc-share-Wl,-soname, libmyab. so.1-o libmyab. so.1.0.1 a. o B. o-lc
-G indicates that debugging information is provided, and-Wall indicates that warning information is generated.
Notes:
(1) It is not recommended to use strip to process shared libraries. It is best not to use the-fomit -- pointer compilation option.
(2)-both fPIC and-fpic can generate independent target code. Generally,-fPIC is used, although the target file may be larger.-fpic produces less code, the execution speed is fast, but there may be restrictions on platform dependencies.
(3) In general, the-Wall,-soname, and your_soname compilation options are required. Of course, the-share option cannot be lost.
4. dynamically load databases
The DL technology allows applications to load and use specified libraries at any time during the running process. This technology is very practical in implementing plug-ins. The concept of dynamic library loading does not focus on the file format of the library, but on usage. There is a set of interface functions so that applications can adopt the DL technology. The following describes these interface functions one by one, and provides an application example at the end.
4.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:
(1) Search by environment variable LD_LIBRARY_PATH
(2) search by/etc/ld. so. cache
(3) 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.
4.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.
4.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. The following is an example:
Dlerror ();/* clear error information */
= Dlsym (handle, "_ name ");
If (error = dlerror ())! = NULL)
{
/* Handle errors */
}
Else
{
/* Find the function */
}
4.4 dlclose
Function prototype: int dlclose (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.
4.5 dynamic library loading example
# I nclude
# I nclude
# I nclude
Int main (int argc, char ** argv)
{
Void * handle;
Double (* cosine) (double );
Char * error;
Dlclose (handle );
Printf ("closed/lib/libm. so.6 \ n ");
Return 0;
}
Compile: gcc-o test. c-ldl. In this example,/lib/libm. so.6 is a dynamic library, while/usr/lib/libdl. so is a shared library.
5. Related Knowledge
5.1 nm command
The nm (1) command can report the symbol list of the database, which is a good tool for viewing information about the database. For more information, see the help documentation. Example:
$ Nm-D libavcodec-0.4.7.so | grep 263
The result is as follows:
00116438 T ff_clean_h263_qscales
00122d14 T ff_h263_decode_end
001223d4 T ff_h263_decode _
00121340 T ff_h263_decode_init
0011048c T ff_h263_decode_mb
0011652c T ff_h263_get_gob_height
0010e664 T ff_h263_resync
00041744 T ff_h263_round_chroma
0010810c T ff_h263_update_motion_val
00115f64 T flv_h263_decode_picture_header
0010da98 T h263_decode_init_vlc
001127c8 T h263_decode_picture_header
001ab040 D h263_decoder
00106c44 T h263_encode_gob_header
0010b2b0 T h263_encode_init
001_d40 T h263_encode_mb
00105f94 T h263_encode_picture_header
001a85a0 D h263_encoder
001162d0 T h263_get_picture_format
0010a7b4 T h263_pred_motion
00106df8 T h263_send_video_packet
001ab180 D h263i_decoder
001a85e0 D h263p_encoder
00115c68 T intel_h263_decode_picture_header
T indicates the normal code segment, and D indicates the initialized data segment.
5.2 database construction and destructor
Generally, you do not need to program the construction and destructor by yourself. If you must do it yourself, the following is a function prototype:
Void _ attribute _ (constructor) my_init (void );
Void _ attribute _ (destructor) my_fini (void );
You cannot use the "-nonstartfiles" or "-nostdlib" option when compiling shared libraries. Otherwise, the build and destructor cannot be executed normally (unless you take certain measures ).
5.3 script sharing Library
In linux, shared libraries can be in the form of scripts. Of course, special scripting languages are required. /Usr/lib/libc. so is a typical example with the following content:
/* GNU ld
Use the shared library, but some s are only in
The static library, so try that secondarily .*/
OUTPUT_FORMAT (elf32-i386)
GROUP (/lib/libc. so.6/usr/lib/libc_nonshared.a)
Script version 5.4 (omitted)
5.5 GNU libtool (omitted)
5.6 remove mark information
The mark information in the shared library is mostly used for debugging, but takes up disk space. If your library is used by an embedded system, it is best to remove the mark information. One method is to use the strip (1) command to view its help documentation. The other method is to use the gnu ld option-s or-S, for example, "-Wl-s" or "-Wl-S ". -S only removes debugging mark information.-s removes all mark information.
5.7 compilation Optimization
I wrote a good article "Whirlwind tutorial On Creating really teensy ELF Executables For Linux ". In this article, we can say that the code of the program has been optimized to the extreme. Some tips may be required in our practical application, but through this article, we can learn more about ELF.
5.8 C ++ and C
To enable the shared library you have compiled to be used by both C and C ++ programs, the header file of the library needs to be prefixed with "extern C". The following is an example:
# Ifndef LIB_HELLO_H
# Define LIB_HELLO_H
# Ifdef _ cplusplus
Extern "C"
{
# Endif
Header file code
# Ifdef _ cplusplus
}
# Endif
# Endif
5.9 about the startup speed of the C ++ Program
The startup speed of C ++ applications is relatively slow. I have been using firefox for a long time. Some people think this is caused by code relocation before the main function is started. An article titled "making C ++ ready for the desktop" (by Waldo Bastian) analyzes this issue. I did not understand it very well.
5.10 Linux Standard Base (LSB)
LSB is a project designed to develop and promote a series of standards, and strive to improve compatibility between different Linux versions, so as to provide consistent interfaces for application development. For more information about linux Standard projects, visit www.linuxbase.org.
Compile the so Library
Shared Object Library
In linux development, many programs require time optimization, such as XFree86 and mozilla. Therefore, high-precision time measurement methods are required. The solution is provided below.
1. Basic Function gettimeofday
# I nclude
# I nclude
Function prototype: int gettimeofday (struct timeval * TV, struct timezone * tz );
Struct timeval {
Time_t TV _sec;/* seconds */
Suseconds_t TV _usec;/* microseconds */
};
Struct timezone {
Int tz_minuteswest;/* minutes W of Greenwich */
Int tz_dsttime;/* type of dst correction */
};
2. Measurement Principle
(1) set the benchmark
(2) obtain the time information at each test point, and the time difference from the benchmark Point serves as the basis for optimization.
3. Sample program
# I nclude
# I nclude
Void consume ()
{
Unsigned int I, j;
Double y;
For (I = 0; I <1000; I ++)
For (j = 0; j <1000; j ++)
Y = I * j;
}
Main ()
{
Struct timeval tpstart, tpend;
Float timeuse;
Gettimeofday (& tpstart, NULL );
();
Gettimeofday (& tpend, NULL );
Timeuse = (tpend. TV _sec-tpstart. TV _sec) +
(Float) tpend. TV _usec-(float) tpstart. TV _usec)/(1000000 );
Printf ("Used Time: % f \ n", timeuse );
}
Void consume ()
{
Int I, j;
For (I = 0; I <10000; I ++)
For (j = 0; j <10000; j ++ );
}
Main ()
{
Timedebug_setstart ();
Consume ();
Timedebug_getcurrent ();
}
Compile:
Gcc-o test. c-lanthony
The execution result can be viewed in/tmp/timedebug. log.
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.