// Author: Andreas F. Borchert
// Description: register functions by their name // hack: MAC OS X is not POSIX conform :( #ifndef __MACH__ #include <link.h> #endif #include <dlfcn.h> #include <string> #include "DynFunctionRegistry.hpp" DynFunctionRegistry::DynFunctionRegistry() { } DynFunctionRegistry::DynFunctionRegistry(const std::string& dir) : dir(dir) { } 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 |