DynamicLibrary.h
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarX::
19 * @author Mirko Waechter ( mirko.waechter at kit dot edu)
20 * @date 2012
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24 
25 #pragma once
26 
27 
28 #include <filesystem>
29 
33 
34 #ifndef _WIN32
35 #include <dlfcn.h>
36 #endif
37 
38 namespace armarx
39 {
40 
41  /**
42  * @class DynamicLibrary
43  * @ingroup core-utility
44  * @brief The DynamicLibrary class provides a mechanism to load libraries at runtime.
45  *
46  * A quick usage example looks as follows:
47  * @snippet ArmarXCore/core/test/DynamicLibraryTest.cpp DynamicLibrary DynamicLibraryUsage
48  */
49  class DynamicLibrary : public Logging
50  {
51  public:
53  ~DynamicLibrary() override;
54  /**
55  * @brief Loads a shared library from the specified path. Throws
56  * exceptions::local::DynamicLibraryException on error.
57  *
58  * @param libPath Path to the library. Can be relative to ArmarXDataPath's
59  * paths.
60  * @throw exceptions::local::DynamicLibraryException
61  * @see ArmarXDataPath
62  */
63  void load(std::filesystem::path libPath);
64 
65  /**
66  * @brief Unloads library. User has to make sure that all references to
67  * the symbols in this library are deleted!
68  * @throw exceptions::local::DynamicLibraryException
69  */
70  void unload();
71 
72  /**
73  * @brief Reloads the current library.
74  *
75  * Useful, if the library has changed since last loading.
76  * @throw exceptions::local::DynamicLibraryException
77  */
78  void reload();
79 
80  /**
81  * @brief Checks if a library is currently loaded.
82  * @return true if a library is loaded.
83  */
84  bool isLibraryLoaded() noexcept;
85 
86  void setUnloadOnDestruct(bool unload);
87 #ifndef WIN32
88  /**
89  * @brief Sets the shared library opening flags and reloads the library,
90  * if a library is already loaded.
91  * @param newFlags flags of ::dlopen()
92  * @throw exceptions::local::DynamicLibraryException
93  */
94  void setFlags(int newFlags);
95 #endif
96 
97  /** @brief Retrieves a symbol (mostly a function) from the loaded library.
98  * The requested function needs to be exported with "extern "C"".
99  * @tparam SymbolType type of the requested symbol
100  * @param functionName name of the requested function
101  * @throw exceptions::local::DynamicLibraryException
102  * @return requested symbol
103  */
104  template <class SymbolType>
105  SymbolType getSymbol(const std::string& functionName);
106 
107  static std::string GetSharedLibraryFileExtension();
108 
109  std::filesystem::path getLibraryFilename() noexcept;
110  std::string getErrorMessage() noexcept;
111 
112  private:
113 #ifdef WIN32
114 
115 #else
116  void* handle;
117  int flags;
118 #endif
119  std::filesystem::path libPath;
120  std::string lastError;
121  bool unloadOnDestruct = true;
122  };
123 
124  using DynamicLibraryPtr = std::shared_ptr<DynamicLibrary>;
125 
126  // /////////////////////////////
127  // / Template Implementation ///
128  // /////////////////////////////
129 
130 
131  template <class SymbolType>
132  SymbolType
133  DynamicLibrary::getSymbol(const std::string& functionName)
134  {
135  if (!handle)
136  {
138  "No library loaded - cannot fetch a symbol");
139  }
140 
141 #ifndef _WIN32
142  dlerror(); // clear error message
143  void* resultRaw = dlsym(handle, functionName.c_str());
144 #endif
145 
146  if (!resultRaw)
147  {
148 #ifndef _WIN32
149  const char* error = dlerror();
150 #endif
151 
152  if (error)
153  {
154  lastError = error;
156  }
157  }
158 
159 #pragma GCC diagnostic push
160 #pragma GCC diagnostic ignored "-Wpedantic"
161  SymbolType result = (SymbolType)(resultRaw);
162 #pragma GCC diagnostic pop
163 
164  if (!result)
165  {
166  lastError = "Could not cast into desired function type";
168  }
169 
170  return result;
171  }
172 } // namespace armarx
armarx::DynamicLibrary::reload
void reload()
Reloads the current library.
Definition: DynamicLibrary.cpp:134
armarx::DynamicLibraryPtr
std::shared_ptr< DynamicLibrary > DynamicLibraryPtr
Definition: DynamicLibrary.h:124
armarx::DynamicLibrary::load
void load(std::filesystem::path libPath)
Loads a shared library from the specified path.
Definition: DynamicLibrary.cpp:54
armarx::DynamicLibrary::GetSharedLibraryFileExtension
static std::string GetSharedLibraryFileExtension()
Definition: DynamicLibrary.cpp:164
armarx::exceptions::local::DynamicLibraryException
This exception is thrown if an invalid value was specified for a property.
Definition: DynamicLibraryException.h:38
armarx::DynamicLibrary::setFlags
void setFlags(int newFlags)
Sets the shared library opening flags and reloads the library, if a library is already loaded.
Definition: DynamicLibrary.cpp:153
armarx::DynamicLibrary::setUnloadOnDestruct
void setUnloadOnDestruct(bool unload)
Definition: DynamicLibrary.cpp:147
armarx::DynamicLibrary::getLibraryFilename
std::filesystem::path getLibraryFilename() noexcept
Definition: DynamicLibrary.cpp:176
armarx::DynamicLibrary::DynamicLibrary
DynamicLibrary()
Definition: DynamicLibrary.cpp:29
armarx::DynamicLibrary::isLibraryLoaded
bool isLibraryLoaded() noexcept
Checks if a library is currently loaded.
Definition: DynamicLibrary.cpp:141
armarx::DynamicLibrary::getErrorMessage
std::string getErrorMessage() noexcept
Definition: DynamicLibrary.cpp:182
armarx::Logging
Base Class for all Logging classes.
Definition: Logging.h:239
armarx::DynamicLibrary::~DynamicLibrary
~DynamicLibrary() override
Definition: DynamicLibrary.cpp:36
armarx::DynamicLibrary::unload
void unload()
Unloads library.
Definition: DynamicLibrary.cpp:106
armarx::DynamicLibrary
The DynamicLibrary class provides a mechanism to load libraries at runtime.
Definition: DynamicLibrary.h:49
Logging.h
armarx::DynamicLibrary::getSymbol
SymbolType getSymbol(const std::string &functionName)
Retrieves a symbol (mostly a function) from the loaded library.
Definition: DynamicLibrary.h:133
ArmarXDataPath.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
DynamicLibraryException.h