// Author: Andreas F. Borchert // Description: register functions by their name #include #include #include #include "DynFunctionRegistry.hpp" DynFunctionRegistry::DynFunctionRegistry() { } DynFunctionRegistry::DynFunctionRegistry(const std::string& dirname) : dir(dirname) { } void DynFunctionRegistry::add(Function* f) { registry[f->get_name()] = f; } // FunctionRegistry::add typedef Function* FunctionConstructor(); Function* DynFunctionRegistry::dynload(const std::string& name) { std::string path = dir; if (path.size() > 0) path += "/"; path += name; path += ".so"; void* handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); if (!handle) return 0; FunctionConstructor* constructor = (FunctionConstructor*) dlsym(handle, "construct"); if (!constructor) { dlclose(handle); return 0; } return constructor(); } bool DynFunctionRegistry::is_known(const std::string& fname) { return get_function(fname) != 0; } // FunctionRegistry::is_known Function* DynFunctionRegistry::get_function(const std::string& fname) { auto it = registry.find(fname); Function* f; if (it == registry.end()) { f = dynload(fname); if (f) { add(f); if (f->get_name() != fname) registry[fname] = f; } } else { f = it->second; } return f; } // FunctionRegistry::get_function