Statically linked libraries and dynamic link library programming under Linux

Statically linked libraries and dynamic link library programming under Linux


reference:

  1. Statically linked libraries and dynamic link library programming under Linux - Histring - blog Park
  2. Mac static and dynamic library creation and use _C / C ++ _ vincent2610 column -CSDN blog

A. Link Library Overview

Library for Linux dynamic and static, dynamic libraries usually .so suffix, with the static .a suffix.

Static link library: When you want to use, the connection will function to find the desired program, and then copy them to the executable file, as this copy is done, so once the connection is successful, the static libraries will not need a

Dynamic link libraries: a program in operation to call a DLL function when the operating system first looks at all the running programs, to see if there's a copy of this library in memory. If so, then let it share the one copy; not only was the link load. When the program is running, the dynamic link library function is called to be placed somewhere in memory, all the calling program will point to this code segment. Therefore, these codes must use a relative address, rather than the absolute address. At compile time, we need to tell the compiler that these object files are used for dynamic link library, so use position-independent code (Position work of the Independent Code (PIC)) .

There are two ways to load dynamic link library: implicit load and display loaded.

Note: The default action is to connect the first connection under linux dynamic library, that is, if there is static and dynamic libraries while not specified, it will be connected to the dynamic library (see Part IV article).


II. Static link library

Here through practical examples to demonstrate to you about, how to compile and use the static and dynamic link library:

2.1 Editing test file

Two files:add.c sub.c add.h sub.h main.c

add.h

#ifndef _ADD_H_
#define _ADD_H_
int add(int a, int b);
#endif

add.c

#include “add.h”
int add(int a, int b)
{
    return a+b;
}

sub.h

#ifndef _SUB_H_
#define _SUB_H_
int sub(int a, int b);
#endif

sub.c

#include “sub.h”
int sub(int a, int b)
{
    return a-b;
}

main.c

#include <stdio.h>
#include “add.h”
#include “sub.h”
int main(void)
{
    printf(“1 + 2 = %d\n”, add(1,2));
    printf(“1 - 2 = %d\n”, sub(1,2));
    return 0;
}

2.2 .c file compiled .o

gcc -c add.c
gcc -c sub.c
Generated files: sub.o, add.o
whether static or dynamic libraries library files are created by .o files.

2.3 will create a static library .a .o file

Original Linux version

ar crlibmymath.a sub.o add.o

MacOs version

ar -cr libmymath.a sub.o add.o

Ar:静态函数库创建的命令
-c :create的意思
-r :replace的意思,表示当前插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误信息,并不替换其他同名的模块。默认的情况下,新的成员增加在库德结尾处。
库文件的命名规范是以lib开头(前缀),紧接着是静态库名,以 .a 为后缀名。

2.4 static library in the program

gcc -o main main.c *-L. –l*mymath

-L 指定函数库查找的位置,注意L后面还有’.’,表示在当前目录下查找
-l则指定函数库名,其中的lib和.a(.so)省略。
注意:-L是指定查找位置,-l指定需要操作的库名。

Static library production is over, how it functions inside of it? Only need to include these prototype declaration public function in the use of these public functions to the source, and then specify a static library name when generating an object file with gcc command (is mymath instead libmymath.a), gcc will from a static library the public functions connected to the target file. Note, gcc will be prefixed with the static lib in front of the library name, and then append a static library file name extension .a get to find the static library file. Main.c in the program, we include the header files add.h and sub.h static library, then call a public function add directly in the main program in main () and sub () can be.

2.5 to generate the target program main, and then run.

./main
1 + 2 = 3
1 - 2 = -1

III. Dynamic library (an implicit link)

3.1 Creating a dynamic library of .so .o

Dynamic library file naming names and static library file name naming convention similar, but also an increase in the dynamic library name prefix lib, but the file extension is .so. For example: We will create a dynamic library named mymath, then the dynamic library file name is libmamath.so. Gcc used to create a dynamic library. Type the following command to get the dynamic library files libmamath.so at the system prompt.

gcc -fPIC-o add.o -c add.c
gcc -fPIC-o sub.o -c sub.c
gcc -shared-o libmamath.so add.o sub.o

or:

gcc –c –o add.oadd.c
gcc –c –o sub.osub.c
gcc -shared -fPCI-o libmyhello.so add.o sub.o

Here:

-fpic:产生代码位置无关代码
-shared :生成共享库

3.2 Implicit way to use dynamic library

These prototype declaration contains a public function in the program using the implicit dynamic library static library and use exactly the same, but also in the use of these public functions to the source, and then specify when generating the target file with the command gcc to compile a dynamic library name. We run the gcc command to generate the target file, and then run it to see the results.

gcc -o main main.c -L. -lmymath
./main
./main: error while loading shared libraries:libmymath.so: cannot open shared object file: No such file or directory

error! ! !
Quick look at the error message, the original can not find the dynamic library files libmyhello.so. The program runs, it needs to find the dynamic library files in / usr / lib and / lib and other directories. If found, the dynamic load library. Otherwise, the program terminated with an error similar to the above operation.

The order of the search path searching dynamic libraries are:

  1. When compiled object code specified dynamic library search path;
  2. LD_LIBRARY_PATH environment variable specified dynamic library search path;
  3. Specified in the configuration file /etc/ld.so.conf dynamic library search path; // Just append the full path to the library where the line in the file as "/ root / test / conf / lib" can then ldconfig It is the change to take effect.
  4. The default DLL search path / lib;
  5. The default dynamic library search path / usr / lib.

To do this Solution:

  1. We will copy the files libmyhello.so to the directory / usr / lib in:
    mv libmyhello.so/usr/lib/
  2. The libmyhello.so copied to the same directory as the main executable file.
    Run again:
./main
1 + 2 = 3
1 - 2 = -1                                            

Success! It also further illustrates the dynamic runtime library is needed.

Initialization and parsing 3.3 dynamic libraries

Loading a dynamic library under Windows, and the unloading initialization function will have to complete the initialization and uninstall function library resource recovery, linux course also be implemented, such initialization functions mainly comprises two parts: structure and mechanism destructor dynamic library, the dynamic global variables library initialization.

(1) construction and destructor mechanism dynamic library

In Linux, provides a mechanism: when loading and unloading the dynamic library, you can write some functions, deal with some appropriate things, we call these functions Constructors and destructors dynamic library, the code format is as follows:
void __attribute__ ((*constructor*)) *my_init*(void); // my_init为自定义的构造函数名
void __attribute__ ((*destructor*)) *my_fini*(void); //my_fini为自定义的析构函数名
at compile share when the library can not be used ”-nonstartfiles”or ”-nostdlib”option, or construction and destructor will not be executed properly (unless you take certain measures).
Note that the argument to the constructor must be empty, the return value must be empty.
For example, ac dynamic library code is as follows:

void __attribute__((constructor)) my_init(void)
{ 
    printf(“init library\n”); 
}

Compiled DLL:
gcc -fPIC -shared a.c -o liba.so
The main program main.c as follows:

#include<stdlib.h>
#include<stdio.h>
int main()
{ 
    pause(); 
    return 0; 
}

Compiler:
gcc -L./ -la main.c -o main.bin
Run main.bin program:
[Image: F32DF0C2-C272-4667-9C55-3023B5361025-1925-0000635E3B680BFD / EDA75E97-F37A-4AFA-9D6A-3C857081945B.png]
In other words, when you run the main, finished loading liba. after so, the initialization function of automatic operation liba.so.

(2) global variable initialization

① example look as follows:

#include<stdlib.h> 
#include<stdio.h> 
int reti()
{ 
    printf(“reti\n”); 
    return 10; 
} 
int g1=reti();  // g1是个全局变量。

GCC compile it using:
gcc -fPIC -shared b1.c -o libb.so

Compile Error! G ++ compile it using:
g++ -fPIC -shared b1.c -o libb.so

Compile successful! Visible GCC and G ++ for this method of global variable initialization, support is not the same.

//主程序
//文件名:main.c
#include <stdlib.h>
#include <stdio.h>
 
int main()
{ 
    pause(); 
    return 0; 
}

Compiled executable file:
gcc -L./ -lb main.c -o main.bin
Run main.bin:

This shows that the process after loading libb.so, in order to initialize global variables g1, which runs reti to initialize g1.
② look at a C ++ example:

//文件名:b2.cpp
class Myclass
{ 
public: 
   Myclass(); 
   int i; 
}; 
 
Myclass::Myclass()
{ 
   printf(“constructMyclass\n”); 
}; 
Myclass g1;

Compile a dynamic library:
g++ -fPIC -shared b2.cpp-o libb.so
In a dynamic library libb.so, declare a global variable of type Myclass g1.

//主程序
//文件名:main.cpp
#include <stdlib.h>
#include <stdio.h>
#include<unistd.h>
 
int main()
{ 
    pause(); 
    return 0; 
}

Compiled executable file:
g++ -L./ -lb main.cpp -o main.bin
Run main.bin:

This shows that the process after loading liba.so, in order to initialize global variables g1, the program will run constructor Myclass before entering the main function.


IV. Dynamic Link Library (explicit link)

4.1 dlfcn.h important header files

Under LINUX use the dynamic link library, the source dlfcn.h need to include the header file, this file defines the dynamic link library function call prototype. The following elaborate these functions.

Function dlerror:

Prototype is: const char *dlerror(void);
When the dynamic link library operations function fails, dlerror can return an error message indicates the operation function succeeds the return value is NULL.

Function dlopen: open the specified dynamic link library files

Prototype: void *dlopen (const char *filename, int flag);
dlopen to open the specified name (filename) dynamic link library, and return to the operating handle.
Filename: If the name does not begin with a /, it is not an absolute path name, locate the file according to the following order:
(1) the value of the LD_LIBRARY user environment variables;
(2) dynamic link buffer file /etc/ld.so.cache
(3) directory / lib, / usr / lib
Flag indicates what time to resolve undefined symbols (call). There are two values:

  1. RTLD_LAZY: show resolve in the dynamic link library function code is executed.
  2. RTLD_NOW: show before dlopen returns to resolve all undefined symbols, once unresolved, dlopen returns an error.
    When Dlopen call fails, it returns NULL value, otherwise return the operating handle.

Function dlsym: Take function performs address

Prototype: void *dlsym(void *handle, char *symbol);
dlsym The dynamic link library operating handle (handle) with a symbol (symbol), return address of the function execution code corresponding to the symbol. Whereby the address can be performed with parameters corresponding function.
Such as program code:

void (*add)(int x,int y); /* 说明一下要调用的动态函数add */
add=dlsym("xxx.so","add"); /* 打开xxx.so共享库,取add函数地址 */
add(89,369); /* 带两个参数89和369调用add函数 */

Function dlclose: Close dynamic link library

Prototype: int dlclose (void *handle);
dlclose for closing the specified handle dynamic link libraries, count only when using this dynamic link library is 0, the system will really be unloaded.

Example 4.2 shows significant loading DLL

In the following example by a dynamic link library loading libmymath.so to invoke add () and sub () two functions.

/*main.c*/
#include <stdio.h>
#include <dlfcn.h>
 
int main(void)
{
       void*dp=*dlopen*(“libmymath.so”,RTLD_LAZY);
       if(NULL==dp)
       {
                printf(“打开动态链接库时失败!”);
                return1;
       }
 
       //定义函数指针
       int(*fn_add)(int,int)=NULL;
       int(*fn_sub)(int,int)=NULL;
       fn_add=*dlsym*(dp,”add”);
       fn_sub=*dlsym*(dp,”sub”);
       if(NULL==fn_add|| NULL==fn_sub)
       {
                printf(“在动态链接库中寻找函数失败!”);
                return1;
       }
       printf(“1+ 2 = %d\n”, fn_add(1, 2));
       printf(“1- 2 = %d\n”, fn_sub(1, 2));
 
       *dlclose*(dp);
       return0;
}

The libmymath.so and main.c in the same directory, execute the following command:
gcc -rdynamic -s -o main.bin main.c -ldl

-rdynamic 选项以指定输出文件为动态链接的方式
-s 指定删除目标文件中的符号表,
-ldl 则指示装配程序ld需要装载dl函数库。

Main.bin last run of results above.

Under Linux and compare load dynamic link library display 4.3 Windows

Windows dynamic link library to ".dll" suffix, and have a dynamic link library under Linux is ".so" suffix.

Function Function Under Windows Linux under
Open to load dynamic link library LoadLibrary dlopen
Get the function address the dynamic link library GetProcAddress dlsym
Close dynamic link library FreeLibrary dlclose
When using the file header contains Winbase.h(include Windows.h) dlfcn.h

V. Special cases

We look back and found that the use of static libraries and implicit way into gcc compiler command target program uses exactly the same as when using dynamic libraries, that when the static and dynamic library when the same name, which gcc command library to use it? Holding of the problem will be sued in the end the mood to give it a try. In addition to first remove all .c and .h files, restored to our state just finished editing the sample program.

gcc -c add.c
gcc -c sub.c
ar crlibmymath.a sub.o add.o
gcc -shared -fPCI -olibmyhello.so sub.o add.o

Now directory has the same name as two library files (DLL files and static library files of the same name):
libmymath.a, libmymath.so
compile and run the program:

gcc -o main main.c -L. -lmymath
./main
./main: error while loading shared libraries:libmymath.so: cannot open shared object file: No       such file or directory

From the results of the program ./main running it is easy to know when Linux Linux static library and dynamic library of the same name, gcc command will give priority to the use of dynamic libraries. If the mandatory use of static libraries will need to add -static option supports, namely:
gcc -static -o main main.c -L. -lmymath
link static executable program significantly larger than the executable file dynamic link library.


VI. Check the library symbol

1, nm command to print out all the symbol library involved. Libraries can be either static or dynamic library.

Three common symbol:
① is called in the library, but not defined in the library (the need to support other libraries), expressed as U
function ② defined in the library, represented by T
③ "weak state" symbols, although they It is defined in the library, but a symbol could be covered with the same name in other libraries, represented by W.

2, with the ldd command to see an executable program depends on shared libraries.


Seven. Linux under so designated export function

Linux compiler so designated function to export the source files inside:

1, in which the top of the file add: #defineDLL_PUBLIC attribute ()) (visibility ( "default")
plus the first two, in which files need to export functions: extern "C" DLL_PUBLIC
3, the Linux dynamic library (so) the default does not export compile time, you need to add in the Makefile: -fvisibility = hidden

Published 304 original articles · won praise 26 · views 120 000 +

Guess you like

Origin blog.csdn.net/qq_31433709/article/details/105320295