当前位置:网站首页>Dlopen() implements dynamic loading of third-party libraries
Dlopen() implements dynamic loading of third-party libraries
2022-07-03 13:53:00 【yolo_ yyh】
Catalog
One 、 Function introduction
Dynamic loading is also called runtime loading , That is, we can decide when to load the specified module when the program is running . In this way, only the necessary modules are loaded when the process starts , Reduced memory usage , Besides, the biggest advantage is , It can be realized without restarting the program , Reload the module . This technology is also called “ Hot update ”.
Let's first look at the function prototype and functions :
// Open the dynamic link library file in the specified mode , And return the handle
void *dlopen(const char *filename, int flags);
// Get the address of the symbol in the shared object or executable file through the handle
void *dlsym(void *handle, const char *symbol);
// Uninstall the open library
int dlclose(void *handle);A simple example to achieve dlopen The dynamic loading function of :
libcaculator.so The main methods of dynamic library are as follows :
int add(int a,int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
int mul(int a, int b)
{
return (a * b);
}
int div(int a, int b)
{
return (a / b);
}Compile and package commands :
gcc -fPIC -shared caculatoe.cc -o libcaculator.so
And then in demo.cc Use in dlopen Open the dynamic library and call the related functions
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
// DLL path
#define LIB_CACULATE_PATH "./libcaculator.so"
// A function pointer
typedef int (*CAC_FUNC)(int, int);
int main()
{
void *handle;
char *error;
CAC_FUNC cac_func = NULL;
// Open the DLL
handle = dlopen(LIB_CACULATE_PATH, RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
// Clear previous errors
dlerror();
// Get a function
*(void **) (&cac_func) = dlsym(handle, "add");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
printf("add: %d\n", (*cac_func)(2,7));
cac_func = (CAC_FUNC)dlsym(handle, "sub");
printf("sub: %d\n", cac_func(9,2));
cac_func = (CAC_FUNC)dlsym(handle, "mul");
printf("mul: %d\n", cac_func(3,2));
cac_func = (CAC_FUNC)dlsym(handle, "div");
printf("div: %d\n", cac_func(8,2));
// Close DLL
dlclose(handle);
exit(EXIT_SUCCESS);
}Compile command :
gcc demo.cc -o demo -ldl
Need links dl library
Compiler error :
./libcaculator.so: undefined symbol: add
use nm see libcaculator.so The generated symbols are as follows :
0000000000004020 b completed.8060
w __cxa_finalize
0000000000001040 t deregister_tm_clones
00000000000010b0 t __do_global_dtors_aux
0000000000003e88 d __do_global_dtors_aux_fini_array_entry
0000000000004018 d __dso_handle
0000000000003e90 d _DYNAMIC
0000000000001158 t _fini
00000000000010f0 t frame_dummy
0000000000003e80 d __frame_dummy_init_array_entry
0000000000002118 r __FRAME_END__
0000000000004000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000002000 r __GNU_EH_FRAME_HDR
0000000000001000 t _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000001070 t register_tm_clones
0000000000004020 d __TMC_END__
00000000000010f9 T _Z3addii
000000000000113e T _Z3divii
0000000000001127 T _Z3mulii
0000000000001111 T _Z3subiiYou can see add Method was renamed by the compiler to _Z3addii, This is because C++ Code at compile time , The compiler does special processing , To support function overloading , The function will be renamed .
The solution is to use extern C, Let the compiler C Language approach to code .
modify caculator.cc The documents are as follows :
#ifdef __cplusplus
extern "C" {
#endif
int add(int a,int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
int mul(int a, int b)
{
return (a * b);
}
int dv(int a, int b)
{
return (a / b);
}
#ifdef __cplusplus
}
#endifThen recompile and run demo that will do

Two 、 Achieve hot update
Modify the file implementation again
demo.h The code is as follows :
#ifndef DEMO_H
#define DEMO_H
#include <stdio.h>
// #include <stdlib.h>
#include <dlfcn.h>
// DLL path
#define LIB_CACULATE_PATH "./libcaculator.so"
// A function pointer
typedef int (*CAC_FUNC)(int, int);
void test(int x);
#endifdemo.cc as follows :
#include "demo.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <thread>
#include <atomic>
void *handle;
std::thread th;
std::atomic<int> flag(0);
std::atomic<bool> start(false);
int hash_load = 0;
void test (int x) {
printf("%d\n", x);
}
void load() {
char *error;
CAC_FUNC cac_func = NULL;
struct stat attr;
time_t start_time;
while(start) {
if (stat(LIB_CACULATE_PATH, &attr) == 0 && attr.st_ino != -1) {
if (attr.st_mtim.tv_sec != start_time && flag == 1) {
printf("start time: %ld, last_time:%ld\n", start_time, attr.st_mtim.tv_sec);
printf("need to close first\n");
start_time = attr.st_mtim.tv_sec;
flag = 0;
dlclose(handle);
}
if (!flag) {
printf("need to open\n");
// Open the DLL
handle = dlopen(LIB_CACULATE_PATH, RTLD_LAZY);
if (!handle) {
// fprintf(stderr, "%s\n", dlerror());
printf("%s\n", dlerror());
continue;
}
// Clear previous errors
start_time = attr.st_mtim.tv_sec;
dlerror();
flag = 1;
// Get a function
*(void **) (&cac_func) = dlsym(handle, "add");
if ((error = dlerror()) != NULL) {
printf("%s\n", error);
continue;
}
printf("add: %d\n", (*cac_func)(2,7));
}
}
sleep(1);
}
return ;
}
void toload() {
start = true;
th = std::thread(load);
}
void tounload() {
start = false;
th.join();
printf("unload \n");
dlclose(handle);
}
int main()
{
toload();
sleep(10);
tounload();
return 0;
}
It's time to rerun demo The executable of , Then modify and recompile libcaculator.so That is to say libcaculator.so Hot update of , The operation results are as follows :

边栏推荐
- Shell timing script, starting from 0, CSV format data is regularly imported into PostgreSQL database shell script example
- [bw16 application] instructions for firmware burning of Anxin Ke bw16 module and development board update
- GoLand 2021.1.1: configure the multi line display of the tab of the open file
- Static linked list (subscript of array instead of pointer)
- SQL Injection (GET/Select)
- MySQL installation, uninstallation, initial password setting and general commands of Linux
- Conversion function and explicit
- Summary of common error reporting problems and positioning methods of thrift
- 【被动收入如何挣个一百万】
- SQL Injection (GET/Search)
猜你喜欢

MySQL installation, uninstallation, initial password setting and general commands of Linux

Go language web development series 28: solve cross domain access of CORS with gin contrib / CORS

Several common optimization methods matlab principle and depth analysis

Go language web development series 27: Gin framework: using gin swagger to implement interface documents

解决MySql 1045 Access denied for user ‘root‘@‘localhost‘ (using password: YES)

Libuv库 - 设计概述(中文版)

Comprehensively develop the main channel of digital economy and digital group, and actively promote the utonmos digital Tibet market
![[机缘参悟-37]:人感官系统的结构决定了人类是以自我为中心](/img/06/b71b505c7072d540955fda6da1dc1b.jpg)
[机缘参悟-37]:人感官系统的结构决定了人类是以自我为中心

Qt学习25 布局管理器(四)

Comprehensive case of MySQL data addition, deletion, modification and query
随机推荐
windos 创建cordova 提示 因为在此系统上禁止运行脚本
Several common optimization methods matlab principle and depth analysis
Go language web development series 26: Gin framework: demonstrates the execution sequence of code when there are multiple middleware
GoLand 2021.1: rename the go project
使用tensorflow进行完整的DNN深度神经网络CNN训练完成图片识别案例
物联网毕设 --(STM32f407连接云平台检测数据)
The network card fails to start after the cold migration of the server hard disk
JSON serialization case summary
AI scores 81 in high scores. Netizens: AI model can't avoid "internal examination"!
Leetcode-1175.Prime Arrangements
Go language unit test 4: go language uses gomonkey to test functions or methods
太阳底下无新事,元宇宙能否更上层楼?
Flutter动态化 | Fair 2.5.0 新版本特性
Summary of common error reporting problems and positioning methods of thrift
Implementation of Muduo accept connection, disconnection and sending data
Stack application (balancer)
Use vscode to view hex or UTF-8 codes
又一个行业被中国芯片打破空白,难怪美国模拟芯片龙头降价抛售了
Qt学习24 布局管理器(三)
Halcon combined with C # to detect surface defects -- Halcon routine autobahn