1. Background
Library: Is the code that has been written and can be used directly in the future.
C + + Static library: Rendezvous into the final generated program, making the resulting file larger . The advantage is that there is no longer any reliance.
C + + Dynamic library: A dynamic library, a file can use multiple code at the same time in memory only one copy, save memory , can be compiled with the main code. The disadvantage is that the header file is required.
The Netizen said: The library is in addition to the main function other code, can compose the library.
2. Only dynamic libraries (active libraries are used in the work)
C + + uses dynamic cubby C language to use dynamic libraries a little more troublesome.
Because C + + supports function overloading (with different number of parameter variables, different parameter types, different type modifiers Const/not const, etc.), it will make C + + rewrite the function name, it is inconvenient to find the corresponding function according to the function name .
In C + +, the corresponding function can be decorated with the extern keyword, which means that the function name is compiled with C speech separation and does not overwrite. (the extern keyword is another keyword-modifying variable that indicates that the variable is already defined in another file.) Usually seen in modified global variables)
3. APIs required to use the so file
Header file #include <dlfcn.h>
Dlopen opens the shared link library in the specified mode. Use can refer to: http://man7.org/linux/man-pages/man3/dlopen.3.html
4. C + + uses dynamic-link library instances
4.1 test.h
1 class test{2public:3 Virtual int Get (); 4 Virtual void Set (constint num); 5 };
4.2 Test.cpp
1#include <iostream>2#include"test.h"3 4 int G_num=0; Global Variables5 6 intTest::Get() {returnG_num;}7 voidTest::Set(Const intnum) {g_num =num;}8 9 #ifdef __cplusplusTen extern "C" { One #endif A -test* Create () {return NewTest;} - the #ifdef __cplusplus - } - #endif
4.3 main.cpp
1#include <iostream>2#include <dlfcn.h>3#include"test.h"4 using namespacestd;5 6 //declaring function Pointers7typedef test* (*so_init) ();8 9 //defines the plug-in class to encapsulate, which needs to be freed after the handle is exhaustedTen structplugin{ One void*handle; ATest *T; - - Plugin (): Handle (NULL), T (null) {} the~Plugin () { - if(t) {Deletet;} - if(handle) {dlclose (handle);} - } + }; - + intCreate_instance (Const Char*so_file, Plugin &p) { A // according to a specific pattern open so file to get the so file handle at //Rtld_now: All undefined symbols need to be resolved before Dlopen returns - //Rtld_deepbind: Search for symbols in the library before searching for global symbols, avoiding conflicts with symbols of the same name -P.handle = Dlopen (so_file, Rtld_now |rtld_deepbind); - if(!p.handle) { -cout <<"cannot open library:"<< Dlerror () <<Endl; - return-1; in } - to // According to the string "create" to read the library corresponding to the function, and return function address , can be understood as an indirect " reflection mechanism " +So_init Create_fun = (so_init) dlsym (P.handle,"Create"); - if(!Create_fun) { thecout <<"Cannot load symbol"<<Endl; * Dlclose (p.handle); $ return-1;Panax Notoginseng } - the //call method, get class instance +P.T =Create_fun (); A the return 0; + } - $ intMain () { $ Plugin p1; - Plugin p2; - the if(0! = Create_instance ("./libtest_1.so", p1) -||0! = Create_instance ("./libtest_2.so", p2)) {Wuyicout <<"Create_instance failed"<<Endl; the return 0; - } Wu -P1.t->Set(1);//To set the global variables in library 1 AboutP2.t->Set(2);//To set the global variables in library 2 $ - //output Two global variables in a library -cout <<"T1 G_num is"<< p1.t->Get() <<Endl; -cout <<"T2 G_num is"<< p2.t->Get() <<Endl; A return 0; +}
Perform:
g++-fpic-shared Test.cpp-o libtest_1.so
g++-fpic-shared Test.cpp-o libtest_2.so
g++-g-wl,--NO-AS-NEEDED-LDL main.cpp-rdynamic
Two global variables can be seen with no interference.
Use of the Linux Dynamic link library (. So)