Explicit call of a dynamic library
Explicit calling means that the library file name appears in the code, and you need
Open and manage library files. The main points are:
(1)Dlfcn. hSystem header file included
(2) Use the dlopen function to open the library file and specify the open mode.
The first parameter of dllope is the name of the shared library, and the specified shared library will be searched in the following location.
① Environment variable LD_LIBRARY_PATH lists all directories separated by semicolons.
② The list of databases found in the file/etc/lD. So. cache is refreshed by the ldconfig command.
③ Directory usr/lib.
④ Directory/lib.
⑤ Current directory.
The second parameter is how to open the shared library. There are two values
① Rtld_now: load all functions in the shared library to the memory.
② Rtld_lazy: pushes back the function loading operation in the shared library until a function is loaded when dlsym () is called.
(3) Use the dlerror () function to test whether the function is successfully opened and handle the error;
(4) use dlsym to obtain the function address and store it in a function pointer.
Then, use the obtained function pointer to call the function.
When the ghost program ends, use dlclose to close the opened dynamic library to prevent resource leakage.
⑺ Use the ldconfig tool to add the dynamic library path to the system library list.
1. Compile the test file
// Main. C test the program explicitly called by the dynamic library
# Include <Dlfcn. h> // System header file used for dynamic Library Management
# Include "myalib. H" // include the function header file. Otherwise, an error is reported during compilation.
Int main (INT argc, char * argv [])
{
// Declare the function pointer of the corresponding function
Void (* Ptest )();
// Load the dynamic library
Void * pdlhandle = dlopen ("libtest. So", rtld_lazy );
// Handle errors
If (pdlhandle = NULL ){
Printf ("failed Load Library/N ");
Return-1;
}
Char * pszerr = dlerror ();
If (pszerr! = NULL)
{
Printf ("% s/n", pszerr );
Return-1;
}
// Obtain the function address
Ptest = dlsym (pdlhandle, "test ");
Pszerr = dlerror ();
If (pszerr! = NULL)
{
Printf ("% s/n", pszerr );
Dlclose (pdlhandle );
Return-1;
}
// Implement function call
(* Ptest )();
// Close the dynamic library when the program ends
Dlclose (pdlhandle );
Return 0;
}
2. Compile the test file and use the-LDL option to specify that the generated object module must use the shared library.
Gcc-O main-LDL main. c
A main file is generated after execution.
3. Execute the test program
Run./main
Output
Test
It indicates the operation is successful.
---------------------------------- Split ------------------------------------------
// Say. c
#include <stdio.h>
int say(char **str){ printf("%s/n",str);
}
|
Compile the shared library generated by say. C:
Gcc-O dlopen. So-shared say. c
// Use the dlopen function to dynamically load the source code of the Library
#include <stdio.h> #include <dlfcn.h> #include <unistd.h>
void show_help(char *msg){ if(msg == NULL){ printf("Usage:mydlopen dlopen.so say stringtosay/n"); }else{ printf("%s/n",msg); } exit(1); } int main(int ac,char ** av){
if(ac < 3){ show_help(NULL); } void *handle; //void *pfunc;
int (*pfunc)(char *str); char * filename = av[1]; char * func = av[2]; char * word = av[3]; char * error; handle = dlopen(filename,RTLD_LAZY); if(!handle){ printf("Error: handle/n"); return 1; }
pfunc = (int (*)(char *))dlsym(handle,func); if((error=dlerror()) != NULL){ printf("Error: dlsym/n"); return 2; } (*pfunc)(word);
dlclose(handle); return 0;
}
|
// Compile the command:
Gcc-O mydlopen. C-LDL
Note:
1. the pointer returned by dlsym is non-typed and the type of the specified function to be converted.
2. When using function pointers: (* pfunc) (Word); cannot be directly written as pfunc (Word); will be wrong
3. C does not support default parameters. When writing show_help, MSG cannot be given the default value of null.
3. Use the dlopen dlsynm dlerror dlclose function in the shared library DL during compilation.
Run the following command:
./Mydlopen./dlopen. So say aaaabbbdddd
------------------------------------ Split ------------------------------------------
Note:pfunc = (int (*)(char *))dlsym(handle,func);
Char * indicates strong conversion of parameters because
INT (* pfunc) (char * Str); defined in this way.
If
INT (* pfunc) (char * STR, int number); defined in this way, you should write the following statements when performing strong conversion:
pfunc = (int (*)(char *,int))dlsym(handle,func);
-------------------------------------- Split -----------------------------------------
For example, the current file directory tree is as follows:
1.work/
2.|--head.h
3.|--main.c
4.|--func.c
5.|--func2.c
At this time, you want to compile func2.c into the dynamic link library dlfunc. So, while the functions in func2.c use the variables and functions in head. h and func. C. The command should be used at this time:
gcc -o dlfunc.so -shared func2.c func.c -I./
In this way, dlfunc. So is generated.
Then compile and connect to the main program.
gcc -o test main.c -ldl -I./
That's all.