当前位置:网站首页>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 _Z3subii
You 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
}
#endif
Then 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);
#endif
demo.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 :
边栏推荐
- Realize the recognition and training of CNN images, and process the cifar10 data set and other methods through the tensorflow framework
- HALCON联合C#检测表面缺陷——HALCON例程autobahn
- logback日志的整理
- Record 405 questions about bank callback post request
- When updating mysql, the condition is a query
- Students who do not understand the code can also send their own token, which is easy to learn BSC
- Which securities company has the lowest Commission for opening an account online? I want to open an account. Is it safe for the online account manager to open an account
- Qt学习20 Qt 中的标准对话框(中)
- 记录关于银行回调post请求405 问题
- 【BW16 应用篇】安信可BW16模组与开发板更新固件烧录说明
猜你喜欢
Setting up remote links to MySQL on Linux
Logback log sorting
GoLand 2021.1: rename the go project
MyCms 自媒体商城 v3.4.1 发布,使用手册更新
Universal dividend source code, supports the dividend of any B on the BSC
Qt学习19 Qt 中的标准对话框(上)
Go: send the get request and parse the return JSON (go1.16.4)
从零开始的基于百度大脑EasyData的多人协同数据标注
如何使用lxml判断网站公告是否更新
MySQL installation, uninstallation, initial password setting and general commands of Linux
随机推荐
JVM系列——概述,程序计数器day1-1
untiy世界边缘的物体阴影闪动,靠近远点的物体阴影正常
Go language web development series 30: gin: grouping by version for routing
怎样删除对象的某个属性或⽅法
Unity embeddedbrowser browser plug-in event communication
Complete DNN deep neural network CNN training with tensorflow to complete image recognition cases
The latest BSC can pay dividends. Any B usdt Shib eth dividend destruction marketing can
The reasons why there are so many programming languages in programming internal skills
The shadow of the object at the edge of the untiy world flickers, and the shadow of the object near the far point is normal
全面发展数字经济主航道 和数集团积极推动UTONMOS数藏市场
使用Tensorflow进行完整的深度神经网络CNN训练完成图片识别案例2
使用tensorflow进行完整的DNN深度神经网络CNN训练完成图片识别案例
Error handling when adding files to SVN:.... \conf\svnserve conf:12: Option expected
Can newly graduated European college students get an offer from a major Internet company in the United States?
Qt学习17 对话框及其类型
Libuv库 - 设计概述(中文版)
Leetcode-1175.Prime Arrangements
When updating mysql, the condition is a query
Go 1.16.4: purpose of go mod tidy
mysql中的字段问题