From 37e49590062c96cfa5f32509a88d5371a4dd83f2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 29 Oct 2016 19:43:42 +0300 Subject: [PATCH] Add a class for loading and accessing modules at runtime --- source/core/module.h | 24 ++++++++++++++++ source/core/module_private.h | 16 +++++++++++ source/core/unix/module.cpp | 40 +++++++++++++++++++++++++++ source/core/unix/module_platform.h | 10 +++++++ source/core/windows/module.cpp | 34 +++++++++++++++++++++++ source/core/windows/module_platform.h | 12 ++++++++ 6 files changed, 136 insertions(+) create mode 100644 source/core/module.h create mode 100644 source/core/module_private.h create mode 100644 source/core/unix/module.cpp create mode 100644 source/core/unix/module_platform.h create mode 100644 source/core/windows/module.cpp create mode 100644 source/core/windows/module_platform.h diff --git a/source/core/module.h b/source/core/module.h new file mode 100644 index 0000000..1d008ba --- /dev/null +++ b/source/core/module.h @@ -0,0 +1,24 @@ +#ifndef MSP_CORE_MODULE_H_ +#define MSP_CORE_MODULE_H_ + +#include + +namespace Msp { + +class Module +{ +private: + struct Private; + + Private *priv; + +public: + Module(const std::string &); + ~Module(); + + void *get_symbol(const std::string &) const; +}; + +} // namespace Msp + +#endif diff --git a/source/core/module_private.h b/source/core/module_private.h new file mode 100644 index 0000000..52d8659 --- /dev/null +++ b/source/core/module_private.h @@ -0,0 +1,16 @@ +#ifndef MSP_CORE_MODULE_PRIVATE_H_ +#define MSP_CORE_MODULE_PRIVATE_H_ + +#include "module.h" +#include "module_platform.h" + +namespace Msp { + +struct Module::Private +{ + ModuleHandle handle; +}; + +} // namespace Msp + +#endif diff --git a/source/core/unix/module.cpp b/source/core/unix/module.cpp new file mode 100644 index 0000000..04b9531 --- /dev/null +++ b/source/core/unix/module.cpp @@ -0,0 +1,40 @@ +#include +#include "module.h" +#include "module_private.h" +#include "systemerror.h" + +using namespace std; + +namespace Msp { + +Module::Module(const string &name) +{ + ModuleHandle handle = dlopen(name.c_str(), RTLD_NOW); + if(!handle) + throw system_error("dlopen", dlerror()); + + priv = new Private; + priv->handle = handle; +} + +Module::~Module() +{ + dlclose(priv->handle); + delete priv; +} + +void *Module::get_symbol(const string &name) const +{ + dlerror(); + void *result = dlsym(priv->handle, name.c_str()); + if(!result) + { + const char *err = dlerror(); + if(err) + throw system_error("dlsym", err); + } + + return result; +} + +} // namespace Msp diff --git a/source/core/unix/module_platform.h b/source/core/unix/module_platform.h new file mode 100644 index 0000000..d40f9e7 --- /dev/null +++ b/source/core/unix/module_platform.h @@ -0,0 +1,10 @@ +#ifndef MSP_CORE_MODULE_PLATFORM_H_ +#define MSP_CORE_MODULE_PLATFORM_H_ + +namespace Msp { + +typedef void *ModuleHandle; + +} // namespace Msp + +#endif diff --git a/source/core/windows/module.cpp b/source/core/windows/module.cpp new file mode 100644 index 0000000..a0301c1 --- /dev/null +++ b/source/core/windows/module.cpp @@ -0,0 +1,34 @@ +#include "module.h" +#include "module_private.h" +#include "systemerror.h" + +using namespace std; + +namespace Msp { + +Module::Module(const string &name) +{ + ModuleHandle handle = LoadLibrary(name.c_str()); + if(!handle) + throw system_error("LoadLibrary"); + + priv = new Private; + priv->handle = handle; +} + +Module::~Module() +{ + FreeLibrary(priv->handle); + delete priv; +} + +void *Module::get_symbol(const string &name) const +{ + FARPROC result = GetProcAddress(priv->handle, name.c_str()); + if(!result) + throw system_error("GetProcAddress"); + + return reinterpret_cast(result); +} + +} // namespace Msp diff --git a/source/core/windows/module_platform.h b/source/core/windows/module_platform.h new file mode 100644 index 0000000..81dfd0f --- /dev/null +++ b/source/core/windows/module_platform.h @@ -0,0 +1,12 @@ +#ifndef MSP_CORE_MODULE_PLATFORM_H_ +#define MSP_CORE_MODULE_PLATFORM_H_ + +#include + +namespace Msp { + +typedef HMODULE ModuleHandle; + +} // namespace Msp; + +#endif -- 2.43.0