Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "MooseError.h" 13 : #include "libmesh/libmesh_config.h" 14 : #include <string> 15 : 16 : #ifdef LIBMESH_HAVE_DLOPEN 17 : #include <dlfcn.h> 18 : #endif 19 : 20 : /** 21 : * Wrapper class to facilitate loading and lifetime management of dynamic libraries and obtaining 22 : * pointers to exported functions. 23 : */ 24 : class DynamicLibraryLoader 25 : { 26 : public: 27 : DynamicLibraryLoader(const std::string & library_file); 28 : ~DynamicLibraryLoader(); 29 : 30 : /** 31 : * Get a function/data pointer of type T to a function exported from the loaded library. 32 : * @param hard_fail Set this to false to return a nullptr if a symbol was not found. 33 : */ 34 : template <typename T> 35 : T getFunction(std::string func, bool hard_fail = true); 36 : 37 : private: 38 : /// Library handle returned by dlopen 39 : void * _handle; 40 : 41 : /// Library file name 42 : const std::string _library_file; 43 : }; 44 : 45 : template <typename T> 46 : T 47 1170 : DynamicLibraryLoader::getFunction(std::string func, bool hard_fail) 48 : { 49 : #ifdef LIBMESH_HAVE_DLOPEN 50 : // clear error 51 1170 : dlerror(); 52 : 53 : // Snag the function pointers from the library 54 1170 : void * pointer = dlsym(_handle, func.c_str()); 55 : 56 : // Catch errors 57 1170 : const char * dlsym_error = dlerror(); 58 1170 : if (dlsym_error && hard_fail) 59 : { 60 0 : dlclose(_handle); 61 0 : mooseError("DynamicLibraryLoader error: Unable to find symbol '", 62 : func, 63 : "' in library '", 64 0 : _library_file, 65 : "'. ", 66 0 : std::string(dlsym_error)); 67 : } 68 : 69 1170 : return *reinterpret_cast<T *>(&pointer); 70 : #else 71 : // this can never be reached as the object instantiation would have already failed 72 : return nullptr; 73 : #endif 74 : }