-
Notifications
You must be signed in to change notification settings - Fork 6
/
SlibLoader.h
126 lines (95 loc) · 3.1 KB
/
SlibLoader.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*-
* Copyright (c) 2018-2019 TAO Zhijiang<taozhijiang@gmail.com>
*
* Licensed under the BSD-3-Clause license, see LICENSE for full information.
*
*/
#ifndef __TZHTTPD_SLIB_LOADER_H__
#define __TZHTTPD_SLIB_LOADER_H__
#include <dlfcn.h>
#include <linux/limits.h>
#include <other/Log.h>
#include "CgiHelper.h"
namespace tzhttpd {
class SLibLoader {
__noncopyable__(SLibLoader)
public:
SLibLoader(const std::string& dl_path) :
dl_path_(dl_path),
dl_handle_(NULL) {
}
~SLibLoader() {
close();
}
std::string get_dl_path() {
return dl_path_;
}
bool init() {
// RTLD_LAZY: Linux is not concerned about unresolved symbols until they are referenced.
// RTLD_NOW: All unresolved symbols resolved when dlopen() is called.
dl_handle_ = dlopen(dl_path_.c_str(), RTLD_LAZY);
if (!dl_handle_) {
roo::log_err("Load library %s failed: %s.", dl_path_.c_str(), dlerror());
return false;
}
// Reset errors
dlerror();
char* err_info = NULL;
module_init_ = (module_init_t)dlsym(dl_handle_, "module_init");
if ((err_info = dlerror()) != NULL) {
roo::log_err("Load func module_init failed: %s", err_info);
return false;
}
// 调用module_init函数
int ret_code = (*module_init_)();
if (ret_code != 0) {
roo::log_err("call module_init failed: %d", ret_code);
return false;
}
module_exit_ = (module_exit_t)dlsym(dl_handle_, "module_exit");
if ((err_info = dlerror()) != NULL) {
roo::log_err("Load func module_exit failed: %s", err_info);
return false;
}
roo::log_warning("module %s load ok!", dl_path_.c_str());
return true;
}
// 函数指针类型
template<typename FuncType>
bool load_func(const std::string& func_name, FuncType* func) {
if (!dl_handle_) {
return false;
}
dlerror();
char* err_info = NULL;
FuncType func_t = (FuncType)dlsym(dl_handle_, func_name.c_str());
if ((err_info = dlerror()) != NULL) {
roo::log_err("Load func %s failed: %s", func_name.c_str(), err_info);
return false;
}
*func = func_t;
roo::log_warning("load func %s from %s ok!", func_name.c_str(), dl_path_.c_str());
return true;
}
void close() {
if (dl_handle_) {
if (module_exit_) {
(*module_exit_)();
module_exit_ = NULL;
roo::log_warning("module_exit from %s called!", dl_path_.c_str());
}
dlclose(dl_handle_);
dl_handle_ = NULL;
roo::log_warning("dlclose from %s called!", dl_path_.c_str());
}
}
private:
// so 模块中需要实现的函数接口,用于模块启动和注销时候的操作
module_init_t module_init_;
module_exit_t module_exit_;
private:
std::string dl_path_;
void* dl_handle_;
};
} // end namespace tzhttpd
#endif // __TZHTTPD_SLIB_LOADER_H__