summaryrefslogtreecommitdiff
path: root/include/dux/sys.d/dobj.hh
diff options
context:
space:
mode:
Diffstat (limited to 'include/dux/sys.d/dobj.hh')
-rw-r--r--include/dux/sys.d/dobj.hh65
1 files changed, 65 insertions, 0 deletions
diff --git a/include/dux/sys.d/dobj.hh b/include/dux/sys.d/dobj.hh
new file mode 100644
index 0000000..5f60b4c
--- /dev/null
+++ b/include/dux/sys.d/dobj.hh
@@ -0,0 +1,65 @@
+/*
+ Copyright 2021 Gabriel Jensen
+
+ This file is part of dux.
+
+ dux is free software:
+ you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ dux is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with dux.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#if defined(dux_os_posix)
+#include <dlfcn.h>
+#endif
+
+namespace dux {
+ class _dobjdat {
+ public:
+#if defined(dux_os_posix)
+ void * dlhandl{nullptr};
+#endif
+ };
+}
+
+template<typename T,typename... Ts> auto ::dux::dobj::call(char const * const dux_restr _fn,Ts const &... _args) -> T {
+ [[maybe_unused]] auto const dat = static_cast<::dux::_dobjdat *>(this->_dat);
+ dux_ass(_fn != nullptr,"Input C-string points to null!");
+#if defined(dux_os_posix)
+ dux_ass(dat->dlhandl != nullptr,"Dynamic object has not been linked!");
+ auto const sym = reinterpret_cast<T (*)(Ts...)>(::dlsym(dat->dlhandl,_fn));
+ if (sym == nullptr) [[unlikely]] {
+ throw ::dux::runerr("Unable to load function!");
+ }
+ return sym(_args...);
+#endif
+}
+::dux::dobj::dobj() : _dat(::new ::dux::_dobjdat) {
+}
+auto ::dux::dobj::link(char const * const dux_restr _lib) -> void {
+ [[maybe_unused]] auto const dat = static_cast<::dux::_dobjdat *>(this->_dat);
+ dux_ass(_lib != nullptr,"Input C-string points to null!");
+#if defined(dux_os_posix)
+ dat->dlhandl = ::dlopen(_lib,RTLD_LOCAL | RTLD_NOW);
+ if (dat->dlhandl == nullptr) [[unlikely]] {
+ throw ::dux::runerr("Unable to open library!");
+ }
+#endif
+}
+auto ::dux::dobj::unlink() noexcept -> void {
+ [[maybe_unused]] auto const dat = static_cast<::dux::_dobjdat *>(this->_dat);
+#if defined(dux_os_posix)
+ if (dat->dlhandl != nullptr) {
+ ::dlclose(dat->dlhandl);
+ dat->dlhandl = nullptr;
+ }
+#endif
+}
+::dux::dobj::~dobj() noexcept {
+ ::delete static_cast<::dux::_dobjdat *>(this->_dat);
+}