Multiple dynamic library code building-project experience accumulation

Source: Internet
Author: User
multiple dynamic library code building

1, Dynamic Library now in our development used more, of course, the benefits do not need to say more. or pull it, hehe!
There are two ways to build a system framework for Linux application-layer program development:
(1) Adopt a process of multiple processes, but each independent process to do their own things, just as we are in the schedule of life in the work of each other, and then need to deal with the process of communication will be able to, while there is one of the greatest advantages, Maintenance people need to focus on their own process can not need to understand what other processes are doing, Linux has a lot of process this thing so it is so fire, I believe most companies are in this way. Come to this company in the beginning I advocated this to do, but unfortunately, I still soy sauce, so still want to use a single process to do all the work. There's no way to figure it out. Another program framework adopts the dynamic library method.
(2) Adopt the way of dynamic library, single process design words must be adopted. Dynamic library is like every process as a module, each dynamic library module to do their own things this is conducive to the maintenance and development of the code. Compared to static libraries, dynamic libraries can be imported directly, while static libraries have to recompile the process every time because it is embedded in the process must be bound, and dynamic is independent. Dynamic library can be loaded flexibly, do not need the library you can not load in, such as a special function of only one customer, it can control the load when the other does not load and the client to do a load. The benefits of not loading are, of course, saving system memory. Save a little bit.


2, if you encounter multiple dynamic library may have 10 8, I whole. How to write the code to be elegant and beautiful, such as dlsym you want to be next to each function are judged. It's exhausting.
So first of all to plan, put forward to common things. Frame to build the other you write your function code on it.
(1) must have a library as a portal to dynamically load the rest of the library, so this library on the so-called "lead brother", this library is generally the process must first be tuned up, generally do some basic system initialization and so on. You can call it the underlying library.
(2) The common characteristics of each dynamic library: Each dynamic library module has its own function name and corresponding module name, that is, it is possible to define a const global structure variable, the name and function pointers are unified into this global variable. The equivalent of the function name Unified management, you later operation only need to operate the global structure of the function pointer on it. The name is the name of each module. Of course, the most suitable location for this definition is in the respective library.
(3) The implementation of each dynamic library loaded by the base library: Each library has a global variable that holds the name of the library and the function name inside the library, and the underlying library can dlopen each library and then dlsym the global variable, and judge each function. Don't be so troublesome, directly judge the name of the next library on the line, functions and other process calls to determine the global variable to point to the function of the pointer is not empty on it. No use, just no use.


(4) Code implementation ideas: According to the above three points,
Dynamic libraries to load: To define a global variable, save the module name and function pointer address.
Base library:
Dlopen Open the library that needs to be loaded, and dlsym the variable in each library, here's the variable that can have the same name in each library because the library is independent. So the base library Dlsym can be simple.
When a dynamic library is loaded, the function pointer is saved in the underlying library, so the function called must be implemented in the underlying library, so there is a struct pointer definition in the underlying library, and the definition of the pointer is consistent with the definitions of each dynamic library, because the implementation of the function is passed in by the underlying library function pointer.


3, on the code
Ⅰ Basic Library code implementation to be unified management of several places: (1) global variable Unified name, (2) Load library Unified with macros to implement, name as an entry can be unified management. (3) Defines the function that the structure body function pointer uses to contract the structure body to point to, the principle is to agree with Fader definition.
Base.h
#define LIB_OBJECT (name) const name# #_t libobj//each library invokes the declaration of a global variable that includes the name of the struct and function pointers, as follows lib1~3 definition so that the uniform name


/* Defines the structure body pointer, defines a function macro to assign the function pointers obtained by DLSYM to each structure body pointer, and to make a judgment on the name of the module.
#define LIB_LOADMODULE (name) \
static const name# #_t *libobj= NULL; \
int name# #_LoadModule (const void *object) \//The name of the macro parameter as the function name
{ \
int iRet; \
\
if (theapiobj) \
Iret=-eexist; \
else {\
Libobj= (typeof (Libobj)) Object; \
if (!strcmp (Libobj->module, #name)) \//Determine if the name of the module and the name of the parameter are consistent
iret= 0; \
else {\
Libobj= NULL; \
Iret=-eperm; \
} \
} \
return iRet; \
}
typedef struct {
const char *module;

Int (*lib1_getmodulever) (char *pszver);
Int (*lib1_set) (const st_set *st_set);
Int (*lib1_open) (const st_open *st_open);
Int (*lib1_init) (const st_init *st_init);
Int (*lib1_check) (void);
Int (*lib1_connect) (St_connect *st_connect);
}llib1_t;


typedef struct {
const char *module;

Int (*lib2_getmodulever) (char *pszver);
Int (*lib2_set) (const st_set *st_set);
Int (*lib2_open) (const st_open *st_open);
Int (*lib2_init) (const st_init *st_init);
Int (*lib2_check) (void);
Int (*lib2_connect) (St_connect *st_connect);
}llib2_t;


typedef struct {
const char *module;

Int (*lib3_getmodulever) (char *pszver);
Int (*lib3_set) (const st_set *st_set);
Int (*lib3_open) (const st_open *st_open);
Int (*lib3_init) (const st_init *st_init);
Int (*lib3_check) (void);
Int (*lib3_connect) (St_connect *st_connect);
}llib3_t;


Base.c
/* Macro definition facilitates centralized management of code * *
#define REGISTERMODULE (name) \
{ \
. libname = #name, \
. LoadModule = name# #_LoadModule, \
}
static const moduletable_t moduletable[] = {
Registermodule (LIB1),
Registermodule (LIB2),
Registermodule (LIB3),
};
/* Start loading the dynamic library and determine if the module name is consistent/*
Handle = Dlopen (ModuleName, Rtld_lazy | Rtld_global);
if (! Handle) {
Api_debug (Dbg_debug, "can" T open \%s\ "\ n", modulename);
retval =-eperm;
Goto Exit_entry;
}

Libobj= Dlsym (Handle, "libobj");
if (! Libobj) {
Api_debug (Dbg_debug, "can ' t resolve \"%s\ "\ n", modulename);
retval =-efault;
Goto Exit_entry;
}




For (i=0 i<sizeof (moduletable)/sizeof (moduletable[0)); i++) {
Api_debug (Dbg_debug, "libname =%s, ModuleName =%s\n", Moduletable[i].libname, ModuleName);
if (Strstr (modulename,moduletable[i].libname)) {///To determine if the library name to be loaded in the underlying library, is currently designed to be a base in which to load what library, can be designed to be flexible
retval = Moduletable[i]. LoadModule (Libobj); Call the macro definition in the. h file to determine if the content name in the library is the same as the name of the library to be loaded by the base library
Api_debug (Dbg_debug, "retval =%d\n", retval);
Goto Exit_entry;
}
}




Exit_entry:
if (retval && handle) {
Dlclose (handle);
if (retval = =-eexist)
retval = 0;
}


Lib1.c this. C in the underlying library, because it is the underlying library that provides function interfaces to the outside, the rest is hidden.
/* Declare struct variables and dynamically loaded library functions, the following function is the use of a case to determine whether the function pointer to the function of the address is null, so you can directly manipulate the functions inside the child library. */
Lib_loadmodule (LIB1)
int Getver (char *pszver)
{
int retval;

if (libobj&& libobj->lib1_getmodulever)
retval = Libobj->lib1_getmodulever (pszver);
else {
retval =-1;
}


return retval;
}


Ⅱ The internal code implementation of each loading library: (1) Define the implementation of each function (2) Define the function address and the name of the module that the struct function pointer points to
#define LIBAPI (func). Func = _# #func


Lib_object (LIB1) = {
. module = "LIB1",

Libapi (Lib1_getmodulever),
Libapi (Lib1_set),
Libapi (Lib1_open),
Libapi (Lib1_init),
Libapi (Lib1_check),
Libapi (Lib1_connect),
};
4. Summary:

The base library provides the function names for each LIB definition, and then the function name of the underlying class calls the function in the subclass according to the function pointer address, but what you see outside is a function of the underlying class, and the subclasses are opaque. If the dynamic library has a lot of cases, this article explains the implementation of the technique is good.

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.