feat: 用Boost.DLL从指定目录用加载动态链接库!
This commit is contained in:
commit
c5204ba3a0
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# clangd的缓存目录
|
||||
.cache
|
||||
# 为clangd创建的compile_commands.json符号链接
|
||||
compile_commands.json
|
16
README.md
Normal file
16
README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# loader
|
||||
|
||||
将`/usr/lib/loader`和`/usr/local/lib/loader`里的动态链接库作为插件加载!
|
||||
|
||||
可以通过`LOADER_PLUGIN_DIRS`覆盖默认插件目录!
|
||||
Linux下用`:`分割路径,Windows下用`;`分割路径。
|
||||
|
||||
为了方便测试,用
|
||||
[just](https://github.com/casey/just)
|
||||
封装了meson!
|
||||
|
||||
```console
|
||||
$ meson setup builddir
|
||||
$ just install
|
||||
$ /usr/local/bin/loader
|
||||
```
|
11
include/interface.hpp
Normal file
11
include/interface.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE Interface {
|
||||
public:
|
||||
virtual const std::string name() const = 0;
|
||||
virtual ~Interface() {}
|
||||
};
|
5
justfile
Normal file
5
justfile
Normal file
@ -0,0 +1,5 @@
|
||||
build:
|
||||
meson compile -C builddir
|
||||
|
||||
install: build
|
||||
meson install -C builddir
|
61
main.cpp
Normal file
61
main.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <cstdlib>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/dll/import.hpp>
|
||||
|
||||
#include "interface.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace dll = boost::dll;
|
||||
|
||||
const vector<string> &get_plugin_dirs() {
|
||||
static vector<string> result;
|
||||
if (!result.empty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
const string delimiter = ";";
|
||||
#else
|
||||
const string delimiter = ":";
|
||||
#endif
|
||||
const char *plugin_dirs = std::getenv("LOADER_PLUGIN_DIRS");
|
||||
if (plugin_dirs != nullptr && *plugin_dirs != '\0') {
|
||||
boost::split(result, plugin_dirs, boost::is_any_of(delimiter));
|
||||
}
|
||||
|
||||
if (result.empty()) {
|
||||
result.push_back("/usr/lib/loader");
|
||||
result.push_back("/usr/local/lib/loader");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
const vector<string> &plugin_dirs = get_plugin_dirs();
|
||||
for (const auto &plugin_dir : plugin_dirs) {
|
||||
fs::path plugin_path(plugin_dir);
|
||||
|
||||
if (!fs::is_directory(plugin_path)) {
|
||||
continue;
|
||||
}
|
||||
for (fs::recursive_directory_iterator dir(plugin_path), end; dir != end; ++dir) {
|
||||
boost::shared_ptr<Interface> plugin;
|
||||
plugin = dll::import_symbol<Interface>(
|
||||
dir->path(),
|
||||
"plugin",
|
||||
dll::load_mode::rtld_lazy
|
||||
);
|
||||
std::cout << "loading plugin: " << plugin->name() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
13
meson.build
Normal file
13
meson.build
Normal file
@ -0,0 +1,13 @@
|
||||
project('loader', 'cpp',
|
||||
default_options: ['cpp_std=c++20'])
|
||||
|
||||
inc = include_directories('include')
|
||||
plugin_dep = declare_dependency(include_directories : inc)
|
||||
|
||||
boost_dep = dependency('boost', modules : ['filesystem'])
|
||||
executable('loader', 'main.cpp',
|
||||
include_directories : inc,
|
||||
dependencies : boost_dep,
|
||||
install : true)
|
||||
|
||||
subdir('plugins')
|
4
plugins/command/meson.build
Normal file
4
plugins/command/meson.build
Normal file
@ -0,0 +1,4 @@
|
||||
command = shared_library('command', 'plugin.cpp',
|
||||
dependencies : plugin_dep,
|
||||
install : true,
|
||||
install_dir : 'lib/loader')
|
17
plugins/command/plugin.cpp
Normal file
17
plugins/command/plugin.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "plugin.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace loader {
|
||||
|
||||
const string Command::name() const {
|
||||
return "command";
|
||||
}
|
||||
Command::~Command() {
|
||||
std::cout << "destructing command" << std::endl;
|
||||
}
|
||||
|
||||
}
|
18
plugins/command/plugin.hpp
Normal file
18
plugins/command/plugin.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "interface.hpp"
|
||||
|
||||
namespace loader {
|
||||
|
||||
class Command : public Interface {
|
||||
public:
|
||||
const std::string name() const;
|
||||
~Command();
|
||||
};
|
||||
|
||||
extern "C" BOOST_SYMBOL_EXPORT Command plugin;
|
||||
Command plugin;
|
||||
|
||||
}
|
1
plugins/meson.build
Normal file
1
plugins/meson.build
Normal file
@ -0,0 +1 @@
|
||||
subdir('command')
|
Loading…
x
Reference in New Issue
Block a user