Runtime loading of dynamic libraries in Linux
In Linux, libraries which are linked during linking stage of the program, gets loaded during the startup of the program, unless a copy is already present in memory.
Another approach provided by Linux operating system is to load/unload the libraries at run time whenever it is needed.
API's are provided by Linux for
Flow:
1. Process begins with a call to dlopen API, providing the path of the shared library and the mode. Main two values for this mode are RTLD_NOW, RTLD_LAZY. This informs the dynamic linker when to perform relocations. RTLD_NOW will make all the necessary relocations at the dlopen call time, whereas RTLD_LAZY will perform relocations only when they're needed. dlopen function returns a handle which is used in all the subsequent API's
2. You then call dlsym() to get the addresses of the symbols (functions)
3. dlerror() function will returns a human readable error message if an API fails
4. When all the functions are accessed of the library, you can unload the shared library with a call to dlclose()
Example Code:
Let's create a shared library which we want to load at runtime using dlopen, dlsym calls
arithmetic.c:
arithmetic.h:
Then write application code for loading this library at run time
main.c:
Output:
Another approach provided by Linux operating system is to load/unload the libraries at run time whenever it is needed.
API's are provided by Linux for
- Loading the Library -- dlopen()
- Looking up for symbols -- dlsym()
- Handling Errors -- dlerror()
- Unloading the Library -- dlclose()
Header File : #include <dlfcn.h>
Note: While building the program, you need to link 'ldl' library: -ldl
Flow:
1. Process begins with a call to dlopen API, providing the path of the shared library and the mode. Main two values for this mode are RTLD_NOW, RTLD_LAZY. This informs the dynamic linker when to perform relocations. RTLD_NOW will make all the necessary relocations at the dlopen call time, whereas RTLD_LAZY will perform relocations only when they're needed. dlopen function returns a handle which is used in all the subsequent API's
2. You then call dlsym() to get the addresses of the symbols (functions)
3. dlerror() function will returns a human readable error message if an API fails
4. When all the functions are accessed of the library, you can unload the shared library with a call to dlclose()
Example Code:
Let's create a shared library which we want to load at runtime using dlopen, dlsym calls
arithmetic.c:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "arithmetic.h" | |
int add(int a, int b) | |
{ | |
return a+b; | |
} | |
int mul(int a, int b) | |
{ | |
return a*b; | |
} | |
int divide(int a, int b) | |
{ | |
if (b != 0) | |
return a/b; | |
return 0; | |
} | |
int sub(int a, int b) | |
{ | |
return a-b; | |
} | |
int power(int a, int b) | |
{ | |
int i; | |
int result = 1; | |
for (i=0; i < b; i++) | |
{ | |
result = result * a; | |
} | |
return result; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __ARITHMETIC_H | |
#define __ARITHMETIC_H | |
int add(int a, int b); | |
int sub(int a, int b); | |
int mul(int a, int b); | |
int divide(int a, int b); | |
int power(int a, int b); | |
#endif |
main.c:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <dlfcn.h> | |
#include "arithmetic.h" | |
int main() | |
{ | |
void *handle; | |
int (*func_power)(int, int); | |
char *error; | |
handle = dlopen("/home/jamal/personal/gcc/dynamic_linking/libarith.so", RTLD_NOW); | |
if (!handle) { | |
fprintf(stderr, "%s\n", dlerror()); | |
exit(EXIT_FAILURE); | |
} | |
func_power = dlsym(handle, "power"); | |
if ((error = dlerror()) != NULL) { | |
fprintf(stderr, "%s\n", error); | |
exit(EXIT_FAILURE); | |
} | |
printf("Power of 2 and 4 is %d\n", func_power(2, 4)); | |
dlclose(handle); | |
exit(EXIT_SUCCESS); | |
} |
nice
ReplyDeleteSuch an informative blog.
ReplyDeleteI also faced a DLL error in my Linux window computer then DLLWin guides me it is happening because sometimes due to malware and guides me to which DLL files I need to keep update or install on my Linux computer for a smooth run of my system. If you require any kind of DLL file either it is the newest or popular file then DLLWin is the place Download DLL Files