Create library functions under Linux

Source: Internet
Author: User

Source:

How to use your own library functions under Linux-riverok-chinaunix blog http://blog.chinaunix.net/uid-21393885-id-88128.html

Build a function library compilation scheme under Linux-Observer log-NetEase blog http://blog.163.com/[email protected]/blog/static/ 23180765201111622915148/

Linux function Library program compilation _ablab_ Sina blog http://blog.sina.com.cn/s/blog_557366df0100l5m1.html

1 Why should I use a library?

There are generally two ways to reuse code.

Paste Copy

This is the least technical content of a scheme. If the code is small, the workload can be tolerated, and if the code is large, this method is undesirable. Even if someone is willing to do this, who can guarantee that all the code will be available?

And the appearance of the library is a good solution to this problem.

Using the Library of functions

Library is a encapsulation mechanism that simply compiles all of the source code into a package after it is compiled into the target.

So how can users know what kind of interface this library provides? Do you want to use NM and other tools to scan individually?

Don't worry, the library developers have done everything well. In addition to the library containing the target code, www.Linuxidc.com typically provides a series of header files that contain the library's interfaces. For the convenience of users, plus a description of the use is almost perfect.

2 Classification of libraries

2.1 Classification of libraries

Depending on the link period, the library also has a static library and a dynamic library of points.

(1) Static library

Usually named *.A.

When the program is compiled, the static library will not function (can be deleted) as long as the program is not recompiled.

Since the code for the static library has been loaded into the executable program during the compilation process, it is large, and if more than one application uses the same static library, there will be multiple copies of the static library on the hard disk where the executable program is stored. If they are running at the same time, there will be multiple copies of this static library in memory. However, compared with the dynamic libraries mentioned below, the program execution time is relatively short because there is no load of library functions at run time. The so-called "space Change Time".

Here we use an example to illustrate the programming and use of static libraries.

Library functions: HELLOWLIB.C

#include

void Printhellow ()

{

printf ("Hellow,now in Lib routine\n");

return;

}

Generate the target file first:gcc-c printhellow.c–o printhellow.o

Then use the AR (archive) command to make a library file of the target file:ar cqs libhello.a printhellow.o

Note that the library file name must be lib***.a format, do not forget to add Lib as a prefix.

Below we write a program called the Printhellow function in the static library LIBHELLO.A.

Testlib.c

int main (int arc, char **argv)

{

Printhellow ();

return;

}

Compile below: Gcc-o testlib testlib.c-l./-lhello

You can generate the executable file testlib.

Note the above- L(uppercase) indicates the path of the library under the current directory. If you do not have this option, you need to add the library LIBHELLO.A to the standard path . such as the/usr/lib. -L (lowercase) only need to be with Hello, all other characters do not, otherwise error.

(2) Dynamic library (shared library)

Typically named. So (Share object)

Unlike a static library, the code for a shared library is loaded into memory when the executable is running, only a simple reference during compilation, so the code is small. Compared with the static library mentioned above, it is very space-saving. However, the runtime needs to be loaded, so the run time is longer relative to the static library. The so-called "change space by Time".

Dynamic linking means that when the program loads the memory, the library function code is actually linked to the address, and even if several programs run at the same time, there is only one function code for the memory.

Dynamic library code to implement such a function, you must meet a condition: can be loaded into different processes of different addresses, so the code to undergo special compilation processing, we have this specially processed code called "Location-independent code (Position independed. PIC) ".

The location-independent code can see that the dynamic code in memory has only one copy, but the data in the dynamic library can be multiple copies. Since each link to a dynamic process can modify the data of the library, the operating system copies a copy of the data whenever this happens, and then modifies the process's address space mapping to point to the new copy of the data, so that the process finally modifies its own piece of data.

In more detail, when a program is running to invoke a dynamic link library function, the operating system will first look at all running programs to see if there is a copy of this library function in memory. If so, let it share that copy; only the link is loaded. This mode, while bringing some "dynamic link" additional overhead, greatly saves the system's memory resources. We know that C's standard library is the dynamic link library, that is, all the programs running in the system share the code snippet of the same C standard library.

As mentioned earlier, because the dynamic link library function is not copied to the executable file. Compile-time compiler will only do some functions such as the name of the check. When the program runs, the called Dynamic link library function is placed somewhere in the memory, and all programs that call it will point to this code snippet. Therefore, the code must be a relative address, not an absolute address. At compile time, we need to tell the compiler that these object files are used to make the dynamic link library, so we use the address-independent code (Position Independent Codes (PIC)).

Shared libraries can also be divided into dynamic links (dynamically linking) and dynamic loading (loading).

dynamic Link (linking)

Specify the library to connect to when compiling the program, and then load the library from the beginning when the program runs. This is also known as an implicit call to a library function.

The sample still uses the steel program to compile the library:

Gcc-fpic-shared-o libhello.so printhellow.c

-fpic indicates that this is an address-independent code,-shared indicates a shared library

Compile the program as you would with a static library: Gcc-o testlib testlib.c-l./-lhello

The compilation was successful, but the following error occurred while we executed Testlib:

./testlib:error while loading shared libraries:libhello.so:cannot load shared object File:no such file or directory

Obviously, the library file is not found in the standard path when the program loads.

Workaround 1) Put our generated library into the standard path.

MV Libhello.so/usr/lib

2) Establish symbolic connection ln-s ' pwd '/libhello.so/usr/lib/libhello.so

3) Append the directory name of the dynamic link library to the dynamic link library configuration file/etc/ld.so.conf

PWD >>/etc/ld.so.conf

Ldconfig

4) Use the dynamic link library to manage command ldconfig, force it to search the specified directory, and update the cache file, # ldconfig ' pwd '

However, this method is only temporary, if you run Ldconfig again, the contents of the cache file may change, the required dynamic link library may not be shared by the system.

5) Load path of the specified library at compile time: Gcc-o testlib testlib.c-l./-LHELLO-WL,-rpath./

Here,-rpath describes the load path of the program runtime Library, because-rpath is an option for the LD command, so GCC needs to use the GCC-wl option when calling it.

dynamically loaded (dynamic loading)

The program does not automatically load the library and needs to be specified by the programmer in the program when it is loaded. The system provides a dynamic load API to facilitate our use.

Let's take a look at these APIs:

1)

#include

void *dlopen (const char *file, int mode);

Dlopen The first parameter is the name of the shared library, and the specified shared library is found in the following path:

① environment variable Ld_library_path specified in the

The list of libraries found in ② file/etc/ld.so.cache is refreshed by the Ldconfig command.

③ directory usr/lib.

④ directory/lib.

⑤ the current directory.

The second parameter is how you open the shared library. has two values

①rtld_now: Load all functions in the shared library into memory

②rtld_lazy: Loading a function in a shared library later, calling Dlsym () to load a function

2)

Char *dlerror ();

Use the Dlerror () function to test whether the opening is successful and error handling;

3)

void *dlsym (void *restrict handle, const char *restrict name);

Use Dlsym to obtain the function address, stored in a function pointer, with the obtained function pointer for function calls.

4)

Char *dlclose (void *handle);

Close the open dynamic Library with Dlclose at the end of the program to prevent resource leaks.

(3) Comparison of static and dynamic libraries

The link Static library is actually a kind of paste copy in a sense, except that it operates on the object code and not the source. Because the static library is linked to the library directly embedded in the executable file, there are two problems.

The first is that the system space is wasted. This is obvious, imagine that if more than one program links the same library, then each generated executable will have a copy of the library, will inevitably waste system space.

Moreover, err, even the well-debugged library, will inevitably be wrong. Once you find a bug in the library, it's a bit of a hassle to save. The program that links the library must be found and then recompiled.

The emergence of dynamic libraries is making up for the disadvantages of static libraries. Because the dynamic library is linked when the program is running, it saves disk space by keeping only one copy on the disk. If you find a bug or want to upgrade it is also very simple, just use the new library to replace the original is OK.

So, is the static library useless?

Answer Yue: not also not also. There is no saying: the existence is reasonable. Since the static library is not lost in the long history of the river, it must have its application. Imagine this situation: if you use the Libpcap library to compile a program, to be run, and his system is not installed Pcap library, how to solve it? The simplest way is to compile the program by linking all the libraries you want to link to their static libraries, so that you can run the program directly on someone else's system.

The so-called win will be lost, because the dynamic library in the program is linked to run, so the speed of the program and link to the static version of the library will inevitably be discounted. However his flaws, the lack of a dynamic library relative to its benefits in today's hardware is simply negligible, so the linker is generally a priority link to the dynamic library when linking, unless you specify the link static library with the-static parameter.

(4) How to tell if a program has a link to a dynamic library?

The answer is to use the file utility.

File program is used to determine the type of files, under the File command, all files will be true.

By the way, a trick. Sometimes in Windows under the browser download tar.gz or tar.bz2 files, suffix name will become strange Tar.tar, to Linux some novice do not know how to extract. However, the file type under Linux is not affected by the file suffix, so we can first use the command file Xxx.tar.tar to look at the file type, and then use the tar and the appropriate parameters to extract.

In addition, you can use the program LDD utility to judge.

LDD is used to print information about all the dynamic libraries that are linked by the target program (as specified by the command line parameters), if the target program does not have a link to the dynamic library, print "Not a dynamic executable", LDD use refer to manpage.

3 Creating your own library

The following is an example of a testdyn.c program:

#include

#include

#include

int main (int arc, char **argv)

{

void (*pfunc) (); /* Pointer of function */

Char *perr;

/* Load Shared library dynamicly */

void *handle = Dlopen ("libhello.so", Rtld_lazy);

if (NULL = = handle)

{

printf ("Dlopen Error,errno =%d\n", errno);

return-1;

}

Perr = Dlerror ();

if (NULL! = perr)

{

printf ("Dlerror first \ n");

return-1;

}

/* Get the address of printhellow function */

Pfunc = Dlsym (handle, "Printhellow");

Perr = Dlerror ();

if (NULL! = perr)

{

printf ("Dlerror when Dlsym \ n");

return-1;

}

/* Call the function */

(*pfunc) ();

Dlclose (handle);

printf ("Load Share library success!\n");

return-1;

}

Compilation:gcc-o testdyn testdyn.c –ldl

Note Add the –ldl parameter.

Program run:

[Email protected] fengxz]#./testdyn

Hellow,now in Lib Routine

Load Share Library success!

Taking hello.c as an example

Create a file hello.c with the following content:

#include

void Hello (void)

{

printf ("Hello world\n");

}

Compile the Hello.c-o libhello.so as a dynamic library with the command gcc-shared. As you can see, there is one more file libhello.so in the current directory.

[[Email protected] test]$ file libhello.so

Libhello.so:ELF 32-bit LSB Shared object, Intel 80386, version 1 (SYSV), not stripped

See, the file type is shared object.

Then edit a test file test.c, which reads as follows:

Int

Main ()

{

Hello ();

return 0;

}

This can be compiled:)

[Email protected] test]$ gcc test.c

/tmp/ccm7w6mn.o:in function ' main ':

TEST.C: (. text+0x1d): Undefined reference to ' hello '

Collect2:ld returned 1 exit status

Link when GCC cannot find the Hello function, compilation failed: (. The reason for this is that Hello is in our own library, and if GCC can find it, it will teach the heck! OK, keep up.

[Email protected] test]$ gcc Test.c-lhello

/usr/lib/gcc/i686-pc-linux-gnu/4.0.0/. /.. /.. /.. /i686-pc-linux-gnu/bin/ld:cannot Find-lhello

Collect2:ld returned 1 exit status

[Email protected] test]$ gcc test.c-lhello-l.

[Email protected] test]$

The first compile directly, GCC by default will be linked to the standard C library, but the symbol name Hello resolution, so the connection phase pass.

Now with GCC Test.c-lhello-l. The compilation was successful and the default output is a.out. Now try to run it:

[Email protected] test]$./a.out

./a.out:error while loading shared libraries:libhello.so:cannot open Shared object file:no such file or directory

Hey, what's going on? Originally although the link when the linker (dynamic linker) found libhello.so, but the dynamic loader (dynamically loader, generally/lib/ld-linux.so.2) but not found. Then look at the output of LDD:

[Email protected] test]$ LDD a.out

Linux-gate.so.1 = (0xffffe000)

libhello.so = not Found

libc.so.6 =/lib/libc.so.6 (0x40034000)

/lib/ld-linux.so.2 (0x40000000)

Sure enough, see no, libhello.so = not found.

Linux provides us with two workarounds:

1. You can add the current path to/etc/ld.so.conf and then run Ldconfig, or run ldconfig with the current path as a parameter (root permission is needed).

2. Add the current path to the environment variable Ld_library_path

Of course, if you feel that it will not cause confusion, you can directly copy the library into the/lib,/usr/lib/and other places (there is no way to avoid, so also have permission), so that the linker and the loader can find the library accurately.

We use the second method:

[Email protected] test]$ export ld_library_path=.: $LD _library_pa

[Email protected] test]$ LDD a.out

Linux-gate.so.1 = (0xffffe000)

libhello.so =/libhello.so (0x4001f000)

libc.so.6 =/lib/libc.so.6 (0x40036000)

/lib/ld-linux.so.2 (0x40000000)

Haha, this next ld-linux.so.2 can find libhello.so this library.

You can now run it directly:

[Email protected] test]$./a.out

Hello World

3.2 Creating a static library

Still use the hello.c and test.c just now.

The first step is to generate the target file.

[Email protected] test]$ gcc-c hello.c

[[email protected] test]$ ls hello.o-l

-rw-r--r--1 Leo users 840 May 6 12:48 hello.o

The second step is to archive the target file.

[email protected] test]$ ar r libhello.a hello.o

Ar:creating LIBHELLO.A

OK,LIBHELLO.A is the static library we created, simple:)

[[Email protected] test]$ file libhello.a

Libhello.a:current AR Archive

The following line of commands teaches you how to link a static library to a program:

[Email protected] test]$ gcc test.c-lhello-l.-static-o hello.static

Let's use the file command to compare the differences between a program that is linked with a dynamic library and a static library:

[Email protected] test]$ gcc test.c-lhello-l.-O hello.dynamic

As previously mentioned, the linker will link the dynamic library by default (this is libhello.so), so just remove the-static parameter from the previous command.

Verify with the file utility whether the executable was generated as requested:

[Email protected] test]$ file hello.static hello.dynamic

Hello.static:ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for Gnu/linux 2.6.6, statically linked, not Stripp Ed

Hello.dynamic:ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for Gnu/linux 2.6.6, dynamically linked (Uses Sha Red Libs), not stripped

You might as well practice the use of LDD:

[Email protected] test]$ LDD hello.static hello.dynamic

Hello.static:

Not a dynamic executable

Hello.dynamic:

Linux-gate.so.1 = (0xffffe000)

libhello.so =/libhello.so (0x4001f000)

libc.so.6 =/lib/libc.so.6 (0x40034000)

/lib/ld-linux.so.2 (0x40000000)

OK, there seems to be no problem, then compare the size of the first:

[Email protected] test]$ ls-l hello. [ds]*

-rwxr-xr-x 1 Leo users 5911 May 6 12:54 hello.dynamic

-rwxr-xr-x 1 Leo users 628182 May 6 12:54 hello.static

See the difference, linking the static library of the target program and link to the dynamic library of the program is a monster!

Such a small program, it is difficult to see the difference in execution time, but for the sake of completeness, take a look at the output of the moment:

[Email protected] test]$ time./hello.static

Hello World

Real 0m0.001s

User 0m0.000s

SYS 0m0.001s

[Email protected] test]$ time./hello.dynamic

Hello World

Real 0m0.001s

User 0m0.000s

SYS 0m0.001s

If the program is relatively large, the effect should be obvious.

Create library functions under Linux

Related Article

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.