LCOV - code coverage report
Current view: top level - include/utils - DynamicLibraryLoader.h (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 6 10 60.0 %
Date: 2025-07-25 05:00:39 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14