The C standard library and C + + STL are examples of shared components that can be linked by our programs. The benefit is that each object file does not need to be stated when it is linked, because the developer can refer to the library in bulk. This simplifies the sharing and reuse of elements between applications.
Library type
- Static library (. a)
- Dynamic libraries (. So): This type of library has only one form, but there are two ways to use it:
- Dynamic linking at run time: This library must be available during the Compile/link phase. These shared objects are not included in the executable component, but are bound to executables.
- Dynamic load/unload, link at execution time (for example: Browser plugin).
Library naming tradition: usually lib
prefixed, all C-standard libraries satisfy this rule. When linking, the command line will not include a prefix or suffix when referencing this library; For example, gcc src-file.c -lm -lpthread
this compilation, Link command, the library referenced during the linking process is the math library m
and the line libraries pthread
, both libraries can be /usr/lib/libm.a
found in and /usr/lib/libpthread.a
. Note: The GNU compiler now has command -pthread
-line options, whereas older versions of compilers need to -lpthread
explicitly specify line libraries. Therefore, you are more likely to see gcc src-file.c -lm -pthread
.
Static library (. a)
Command:cc -Wall -c ctest1.c ctest2.c
- Options
-Wall:包含警告,可以看到警告的帮助页
- Create a
libctest.a
library:ar -cvq libctest.a ctest1.o ctest2.o
- List the files that the library contains:
ar -t libctest.a
- Link This library:
- Cc-o exe PROG.C LIBCTEST.A
- Cc-o EXE Prog.c-l/path/to/library-dir-lctest
Note: When a library is created, after a command-line link and an executable program is generated, a symbol table is created in the executable's archive, the executable embeds the ar
command, and for ms/windows developers, .a
the .lib
Library and Visual C + + Library.
Dynamically linked Shared Object library (. So)
Generate a Shared library method: (Dynamic Link Object library file)
- Create an object code
- Create a library
- Optional: Use symbolic links to create a default version
Create a library instance
gcc -Wall -fPIC -c *.cgcc -shared -W1,-soname,libctest.so.1 -o libctest.so.1.0 *.omv libctest.so.1.o /opt/libln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so
This creates a libctest.so.1.o
symbolic link to it and a pointer to it. It is also legal to cascade Links:
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1ln -sf /opt/lib/libctest.so.1 /opt/lib/libctest.so
If you look at all the libraries under/lib and/usr/lib, both of these methods exist, and the Linux developers are not unified. It is important that the symbolic link ultimately points to the real library file.
-wall: Contains warnings;
-fpic: The compiler outputs a standalone code location, a feature required for shared libraries;
-shared: Produces a shared library object that can be linked by other objects to form an executable program;
-WL: Optional, transfer option to linker; In the example above, "-soname libctest.so.1 被传递; -o:运算输出,共享对象的名字为
libctest.so.1.0"
Links to libraries:
- Link/opt/lib/libctest.so allow compilation to
-lctest
execute;
- Link/OPT/LIB/LIBCTEST.SO.A ' Allow run-time bindings to run;
Compiling the main program and linking the shared object library
gcc -Wall -I/path/to/include-flies -L/path/to/libraries prog.c -lctest -o prog
gcc -Wall -L/opt/lib prog.c -lctest -o prog
The name of the shared library is libctest.so
, that's why you need to create a symbolic link, otherwise you'll get/usr/bin/ld:cannot find-lctest error. These libraries are not included in the executable program and are dynamically linked during the run.
Dependency List
The shared libraries that the executable program relies on can be enumerated by the ' LDD name-of-executable, and unresolved errors in the shared connection library may cause the program to run incorrectly when the library is loaded.
For example
[prompt]$ ldd libname-of-lib.so libglut.so.3 => /usr/lib64/libglut.so.3 (0x00007fb582b74000) libGL.so.1 => /usr/lib64/libGL.so.1 (0x00007fb582857000) libX11.so.6 => /usr/lib64/libX11.so.6 (0x00007fb582518000) libIL.so.1 (0x00007fa0f2c0f000) libcudart.so.4 => not found
The first three libraries indicate that there is a path, and then two have problems. Resolve the dependencies of the latter two libraries:
- Method One: Add the path to the parse library to/etc/ld.so.conf.d/name-of-lib-x86_64.conf and/or/etc/ld.so.conf.d/name-of-lib-i686.conf, and then use
sodu ldconfig
the Load the library cache again
- Method Two: Add the library and path to the Compile/link command:-lname-of-lib-l/path/to/lib
- Method Three: Add the library path to the environment variable to solve the run dependency problem: Export ld_library_path= $LD _library_path:/path/to/lib
Run the program
- Set path: Export ld_library_path=/opt/lib: $LD _library_path
- Run: Prog
Main noun:
- C Compiler for GCC-GNU
- LD-GNU's linker
- LDD-list dependencies for a library
- Ldconfig-Configure the Dynamic linker Runtime binding object (that is, update the cache/etc/ld.so.cache)
Library Path
In order for the executable program to find the required libraries and link them at run time, the system must be configured with the following configuration methods:
- Add the library directory that you want to include in the dynamic link to the/etc/ld.so.conf file, and perform the ldconfig (root permission) to configure the linker to bind the object at runtime. You can use
-f file-name
identities to refer to other configuration files.
- Add the specified directory to the library cache: Ldconfig-n/opt/lib. Where/opt/lib is the directory that contains your library ctest.so, but this is not permanent for the system and will be lost after a reboot. For example, the current directory
ldconfig -n .
, links can be used -L.
.
- Specifies the environment variable Ld_library_path, which contains the directory where the shared library resides. Export ld_library_path=/opt/lib: $LD _library_path, or edit the ~/.BASHRC file:
...if [ -d /opt/lib ];then LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATHfi...export LD_LIBRARY_PATH
Library information
AR: List all object files in the archive library
ar tf /usr/lib/x86_64-linux-gnu/libjpeg.a
NM: enumeration of symbols, including object files, archive libraries, and shared libraries
nm file.o
#列举对象文件中包含的符号
nm /usr/lib/x86_64-linux-gnu/libjpeg.a
#列举包含在archive库中的符号.
Use the-D column to include large amounts of symbols in an object file or in a shared library.
Dynamically load and unload shared libraries using LIBDL
These libraries can be dynamically loaded/unloaded at execution time.
The library's include file Ctest.h is as follows: extern "c"
easy to use the library can be used in C and C + +. This statement prevents the link from being parsed as a result of a C + + name isolation.
#ifndef CTEST_H#define CTEST_H#ifdef __cplusplusextern"C" {#endifvoid ctest1(int *);void ctest2(int *);#ifdef __cplusplus}#endif#endif
Dynamically load or unload the libctest.so library (PROGDL.C):
#include <stdio.h>#include <dlfcn.h>#include "ctest.h"intMainintargcChar**ARGV) {void*lib_handle;Double(*FN) (int*);intXChar*error; Lib_handle = Dlopen ("/opt/lib/libctest.so", Rtld_lazy);if(!lib_handle) {fprintf (stderr,"%s\n", Dlerror ()); Exit1); } fn = Dlsym (Lib_handle,"Ctest1");if(Error = Dlerror ())! = NULL) {fprintf (stderr,"%s\n", error); Exit1); } (*FN) (&x); printf"valx=%d\n", x); Dlclose (Lib_handle);return 0;}
Compile command:gcc -rdynamic -o progdl progdl.c -ldl
Explain:
- Dlopen ("/opt/lib/libctest.so", Rtld_lazy); Opens a shared connection library named "Libctest.so", the second parameter shows the binding, defined in the Dlfcn.h file, and returns null if it fails.
Option: Rtld_lazy: If specified, Linux does not care about unresolved symbols until referenced; Rtld_now: All unresolved symbols are parsed at call Dlopen, Rt_global, so that the symbol library is visible.
- Dlsym (Lib_handle, "ctest1"); Swap back the function address of the loaded shared library, or null if the failed return value. Note: When using C + + functions, first use NM to find the mangles symbol name, or use extern "C" to avoid name mangling. For example, extern "C" void Function-name ();
C + + class objects and dynamically loaded C + + and name decorations (name mangling)
When compiling the C example above using C + +, you will find that the C + + function name is modified to be unavailable unless the function definition is extern "C"{}
protected.
Note that the following two are not equivalent:
//1:extern"C" { int functionx();}//2:extern"C"int functionx();
The following two are equivalent:
//1:extern"C" { externint functionx();}//2:extern"C"int functionx();
Dynamically loading C + + classes:
The dynamic library loader allows programmers to load C functions. In C + +, we want to load the member functions of a class, in fact, the entire class can be in the library, we first load and access the entire object and its member functions. Can be achieved by passing the class "C" Factory function.
The header file for the class is as follows:
class Abc {......};// Class factory "C" functionstypedef Abc* create_t;typedefvoid destroy_t(Abc*);
The corresponding CPP files are as follows:
Abc::Abc(){ ...}extern"C"{ // These two "C" functions manage the creation and destruction of the class Abc Abc* create() { returnnew Abc; } void destroy(Abc* p) { delete p; // Can use a base class or derived class pointer here }}
This CPP file is the source file for the library, and the C function instantiates and destroys a class in the library dynamically loading the library, and ABC is the class.
The method that contains the main executable calling this library is as follows:
// load the symbols "create");...... "destroy");......
Note: The New/delete of C + + classes should be provided by executable programs or libraries and should not be separated. So that if a new/delete overload occurs on one side, it does not cause an unexpected condition.
and DLL comparison
Windows and Linux/unix shared objects (. So) correspond to the. dll, which is usually a. dll under Windows, and sometimes. ocx. On older 16-bit systems, the dynamic-link library may also be an. exe. Unfortunately, the build of the DLL under Windows is tightly integrated with the Microsoft IDE, and no IDE has a basic way of generating it yourself.
Functions for Windows C + +:
- :: LoadLibrary ()-Dlopen ()
- :: GetProcAddress ()-dlsym ()
- :: FreeLibrary ()-dlclose ()
Cross-platform Code snippets
Include header file (. h/.hpp):
class Abc{public: static// Function declaration. Could also be used as a public class member function.private: static Abc *mInstance; // Singleton. Use this declaration in C++ class member variable declaration. ...}
The corresponding CPP file:
///Singleton instantiationabc* abc::minstance =0;//Use this declaration for C + + class member variable //(Defined Outside of class definition in ". cpp" file)//Return unique pointer to instance of ABC or create it if it does not exist.//(Unique to both EXE and DLL)Staticabc* abc::instance ()//Singleton{#ifdef WIN32 //If pointer to instance of the ABC exists (true) then return instance pointer else look for //instance pointer in memory mapped pointer. If The instance pointer does not exist in //memory mapped pointer, return a newly created pointer to an instance of ABC. returnMinstance? Minstance: (minstance = (abc*) memorymappedpointers::getpointer ("ABC")) ? Minstance: (minstance = (abc*) memorymappedpointers::createentry ("ABC",(void*)NewABC));#else //If pointer to instance of the ABC exists (true) then return instance pointer /Else return a newly created pointer to an instance of ABC. returnMinstance? Minstance: (minstance =NewABC);#endif}
The Windows linker will link to two object instances, one in EXE and one within the Loadable module. The memory-mapped pointer makes it clear that both the EXE and the Loadable library point to the same variable or object. The GNU linker does not have this problem.
Cross-platform Loadable library programming:
#ifndef use_precompiled_headers#ifdef WIN32#include <direct.h>#include <windows.h>#else#include <sys/types.h>#include <dlfcn.h>#endif#include <iostream>#endif using namespaceStd#ifdef WIN32HINSTANCE Lib_handle;#else void*lib_handle;#endif //Where RetType is the pointer to a return type of the function //This return type can be int, float, double, etc or a struct or class. typedefRettype* func_t;//Load the library-------------------------------------------------#ifdef WIN32String Nameoflibtoload ("C:\opt\lib\libctest.dll"); Lib_handle = LoadLibrary (TEXT (Nameoflibtoload.c_str ()));if(!lib_handle) {Cerr <<"Cannot load library:"<< TEXT (Nameofdlltoload.c_str ()) << Endl; }#elseString Nameoflibtoload ("/opt/lib/libctest.so"); Lib_handle = Dlopen (Nameoflibtoload.c_str (), rtld_lazy);if(!lib_handle) {Cerr <<"Cannot load library:"<< dlerror () << Endl; }#endif.........//load the symbols-------------------------------------------------#ifdef WIN32func_t* Fn_handle = (func_t*) GetProcAddress (Lib_handle,"Superfunctionx");if(!fn_handle) {Cerr <<"Cannot load symbol Superfunctionx:"<< GetLastError () << Endl; }#else //Reset ErrorsDlerror ();//load the symbols (handle to function "Superfunctionx")func_t* fn_handle= (func_t*) dlsym (Lib_handle,"Superfunctionx");Const Char* Dlsym_error = Dlerror ();if(Dlsym_error) {Cerr <<"Cannot load symbol Superfunctionx:"<< dlsym_error << Endl; }#endif.........//Unload the library-----------------------------------------------#ifdef WIN32FreeLibrary (Lib_handle);#elseDlclose (Lib_handle);#endif
"Ubuntu" Linux link library