LCOV - code coverage report
Current view: top level - utilities/include/mcrl2/utilities - dynamiclibrary.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 30 38 78.9 %
Date: 2024-04-19 03:43:27 Functions: 8 10 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Jeroen Keiren, Sjoerd Cranen
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : /// \file mcrl2/utilities/dynamic_library.h
      10             : 
      11             : 
      12             : #ifndef MCRL2_UTILITIES_DYNAMIC_LIBRARY_H
      13             : #define MCRL2_UTILITIES_DYNAMIC_LIBRARY_H
      14             : 
      15             : #include "mcrl2/utilities/logger.h"
      16             : #include "mcrl2/utilities/platform.h"
      17             : 
      18             : #ifdef MCRL2_PLATFORM_WINDOWS
      19             :   #include <windows.h>
      20             :   typedef HMODULE library_handle;
      21             :   typedef FARPROC library_proc;
      22             : 
      23             :   inline
      24             :   library_handle get_module_handle(const std::string& fname)
      25             :   {
      26             :     return LoadLibrary(fname.c_str());
      27             :   }
      28             : 
      29             :   inline
      30             :   library_proc get_proc_address(library_handle handle, const std::string& procname)
      31             :   {
      32             :     return GetProcAddress(handle, procname.c_str());
      33             :   }
      34             : 
      35             :   inline
      36             :   bool close_module_handle(library_handle handle)
      37             :   {
      38             :     return FreeLibrary(handle);
      39             :   }
      40             : 
      41             :   inline
      42             :   std::string get_last_error()
      43             :   {
      44             :     std::string result;
      45             :     char *buffer = 0;
      46             :     DWORD last = GetLastError();
      47             :     DWORD x = FormatMessage(
      48             :       FORMAT_MESSAGE_ALLOCATE_BUFFER | // Let Windows allocate string
      49             :       FORMAT_MESSAGE_FROM_SYSTEM,      // Retrieve a system error message
      50             :         nullptr,               // No source needed
      51             :         last,               // Requested error message
      52             :         0,             // Default language
      53             :         reinterpret_cast<LPSTR>(&buffer), // Output buffer
      54             :         0,             // Minimum allocation size
      55             :         nullptr             // No arguments here
      56             :       );
      57             :     if (x)
      58             :     {
      59             :       result = buffer;
      60             :     }
      61             :     else
      62             :     {
      63             :       result = "Unknown error.";
      64             :     }
      65             :     LocalFree(buffer);
      66             :     return result;
      67             :   }
      68             : #else
      69             :   #include <dlfcn.h>
      70             :   typedef void* library_handle;
      71             :   typedef void* library_proc;
      72             : 
      73             :   inline
      74           5 :   library_handle get_module_handle(const std::string& fname)
      75             :   {
      76             :     // return dlopen(fname.c_str(), RTLD_LAZY);
      77           5 :     return dlopen(fname.c_str(), RTLD_NOW);
      78             :   }
      79             : 
      80             :   inline
      81           5 :   library_proc get_proc_address(library_handle handle, const std::string& procname)
      82             :   {
      83           5 :     return dlsym(handle, procname.c_str());
      84             :   }
      85             : 
      86             :   inline
      87           5 :   bool close_module_handle(library_handle handle)
      88             :   {
      89           5 :     return (dlclose(handle) == 0);
      90             :   }
      91             : 
      92             :   inline
      93           0 :   std::string get_last_error()
      94             :   {
      95           0 :     return std::string(dlerror());
      96             :   }
      97             : #endif
      98             : 
      99             : class dynamic_library 
     100             : {
     101             :   protected:
     102             :     library_handle m_library;
     103             :     std::string m_filename;
     104             : 
     105           5 :     void load() 
     106             :     {
     107           5 :       if (m_library == nullptr)
     108             :       {
     109           5 :         m_library = get_module_handle(m_filename.c_str());
     110           5 :         if (m_library == nullptr)
     111             :         {
     112           0 :           throw std::runtime_error("Could not load library (" + m_filename + "): " + get_last_error());
     113             :         }
     114             :       }
     115           5 :     }
     116             :   
     117           5 :     void unload() 
     118             :     {
     119           5 :       if (m_library!=nullptr)
     120             :       {
     121           5 :         if (!close_module_handle(m_library))
     122             :         {
     123           0 :           throw std::runtime_error("Could not close library (" + m_filename + "): " + get_last_error());
     124             :         }
     125           5 :         m_library = nullptr;
     126             :       }
     127           5 :     }
     128             :   
     129             :   public:
     130           5 :     dynamic_library(const std::string& filename = std::string()) 
     131           5 :      : m_library(nullptr), 
     132           5 :        m_filename(filename) 
     133             :     {
     134           5 :     }
     135             : 
     136           5 :     virtual ~dynamic_library() 
     137           5 :     {
     138             :       try
     139             :       {
     140           5 :         unload();
     141             :       }
     142           0 :       catch(std::runtime_error& error)
     143             :       {
     144           0 :         mCRL2log(mcrl2::log::error) << "Error while unloading dynamic library: " << error.what() << std::endl;
     145           0 :       }
     146           5 :     }
     147             :   
     148           5 :     library_proc proc_address(const std::string& name) 
     149             :     {
     150           5 :       if (m_library == nullptr)
     151             :       {
     152           5 :         load();
     153             :       }
     154           5 :       library_proc result = get_proc_address(m_library, name.c_str());
     155           5 :       if (result == 0)
     156             :       {
     157           0 :         throw std::runtime_error("Could not find proc address (" + m_filename + ":" + name + "): " + get_last_error());
     158             :       }
     159           5 :       return result;
     160             :     }
     161             : };
     162             : 
     163             : #endif // MCRL2_UTILITIES_DYNAMIC_LIBRARY_H

Generated by: LCOV version 1.14