← index
MXVM/include/mxvm/function.hpp
Source: MXVM/include/mxvm/function.hpp
#ifndef __FUNCTION_H__
#define __FUNCTION_H__

#include <dlfcn.h>
#include <iostream>
#include <stdexcept>
#include <string>

namespace mxvm {

    template <typename Sig>
    class Function;
    template <typename R, typename... Args>
    class Function<R(Args...)> {
      public:
        using Fn = R (*)(Args...);
        Function(char const *lib, char const *name) {
            handle = dlopen(lib, RTLD_LAZY);
            if (!handle)
                throw std::runtime_error(dlerror());
            void *sym = dlsym(handle, name);
            if (!sym) {
                dlclose(handle);
                throw std::runtime_error(dlerror());
            }
            fn = reinterpret_cast<Fn>(sym);
        }

        Function(char const *name) {
            handle = dlopen(nullptr, RTLD_LAZY);
            if (!handle)
                throw std::runtime_error(dlerror());
            void *sym = dlsym(handle, name);
            if (!sym) {
                dlclose(handle);
                throw std::runtime_error(dlerror());
            }
            fn = reinterpret_cast<Fn>(sym);
        }

        ~Function() {
            if (handle)
                dlclose(handle);
        }
        R operator()(Args... args) const {
            if (!fn)
                throw std::runtime_error("Null function pointer");
            return fn(std::forward<Args>(args)...);
        }

      private:
        void *handle = nullptr;
        Fn fn = nullptr;
    };

} // namespace mxvm

#endif