YourOwnPluginLoader.hpp
class YourOwnPluginLoader
{
public:
explicit YourOwnPluginLoader(const std::string &plugin);
~YourOwnPluginLoader() final;
void *dlsym(const std::string &symbol) final;
private:
void *handle_ = nullptr;
};
YourOwnPluginLoader.cpp
#include "YourOwnPluginLoader.h"
#include <dlfcn.h>
YourOwnPluginLoader::YourOwnPluginLoader(const std::string &plugin)
{
std::string full_path = std::string("/usr/lib64/yourown/") + plugin;
handle_ = dlopen(full_path.c_str(), RTLD_NOW | RTLD_LOCAL);
if (handle_ == nullptr)
{
//err log
}
}
YourOwnPluginLoader::~YourOwnPluginLoader()
{
if(handle_ != nullptr) dlclose(handle_);
}
void *YourOwnPluginLoader::dlsym(const std::string &symbol)
{
if (handle_ == nullptr)
{
return nullptr;
}
auto ret(::dlsym(handle_, symbol.c_str()));
return ret;
}
符号查找
plugin加载以及符号查找
template<typename ReturnType, typename... Params>
std::function<ReturnType(Params...)> pluginResolveFunc(const std::string &symbolName,
const std::string &pluginName) noexcept
{
typedef std::unordered_map<std::string, std::shared_ptr<YourOwnPluginLoader>> PluginMap;
static PluginMap plugin_holder;
std::shared_ptr<YourOwnPluginLoader>instance;
auto it = plugin_holder.find(pluginName);
if(it == plugin_holder.end())
{
instance = std::make_shared<YourOwnPluginLoader>(pluginName);
plugin_holder.insert({pluginName, instance});
} else
{
instance = it->second;
}
void *ptr(instance->dlsym(symbolName));
typedef ReturnType (*FunctionType)(Params...);
FunctionType functionPtr((FunctionType) ptr);
return std::function<ReturnType(Params...)>(functionPtr);
}
用法样例
假使当前 libyourownpoxyplugin.so里面有一个符号用于创建proxy的instance
extern "C" std::unique_ptr<YourOwnProxyInterface> g_createYourOwnProxyHandler(uint32_t);
std::unique_ptr<YourOwnProxyInterface>create()
{
try
{
static auto createHandler =
pluginResolveFunc<std::unique_ptr<YourOwnProxyInterface>,uint32_t>(
"g_createYourOwnProxyHandler", "libyourownpoxyplugin.so");
return createHandler(9527);
}
catch (const std::exception &e)
{
//err log
return nullptr
}
}