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 
31 
32 #include <filesystem>
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  */
50  public Logging
51  {
52  public:
54  ~DynamicLibrary() override;
55  /**
56  * @brief Loads a shared library from the specified path. Throws
57  * exceptions::local::DynamicLibraryException on error.
58  *
59  * @param libPath Path to the library. Can be relative to ArmarXDataPath's
60  * paths.
61  * @throw exceptions::local::DynamicLibraryException
62  * @see ArmarXDataPath
63  */
64  void load(std::filesystem::path libPath);
65 
66  /**
67  * @brief Unloads library. User has to make sure that all references to
68  * the symbols in this library are deleted!
69  * @throw exceptions::local::DynamicLibraryException
70  */
71  void unload();
72 
73  /**
74  * @brief Reloads the current library.
75  *
76  * Useful, if the library has changed since last loading.
77  * @throw exceptions::local::DynamicLibraryException
78  */
79  void reload();
80 
81  /**
82  * @brief Checks if a library is currently loaded.
83  * @return true if a library is loaded.
84  */
85  bool isLibraryLoaded() noexcept;
86 
87  void setUnloadOnDestruct(bool unload);
88 #ifndef WIN32
89  /**
90  * @brief Sets the shared library opening flags and reloads the library,
91  * if a library is already loaded.
92  * @param newFlags flags of ::dlopen()
93  * @throw exceptions::local::DynamicLibraryException
94  */
95  void setFlags(int newFlags);
96 #endif
97 
98  /** @brief Retrieves a symbol (mostly a function) from the loaded library.
99  * The requested function needs to be exported with "extern "C"".
100  * @tparam SymbolType type of the requested symbol
101  * @param functionName name of the requested function
102  * @throw exceptions::local::DynamicLibraryException
103  * @return requested symbol
104  */
105  template <class SymbolType>
106  SymbolType getSymbol(const std::string& functionName);
107 
108  static std::string GetSharedLibraryFileExtension();
109 
110  std::filesystem::path getLibraryFilename() noexcept;
111  std::string getErrorMessage() noexcept;
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  using DynamicLibraryPtr = std::shared_ptr<DynamicLibrary>;
124 
125 
126  // /////////////////////////////
127  // / Template Implementation ///
128  // /////////////////////////////
129 
130 
131 
132  template <class SymbolType>
133  SymbolType DynamicLibrary::getSymbol(const std::string& functionName)
134  {
135  if (!handle)
136  {
137  throw exceptions::local::DynamicLibraryException("No library loaded - cannot fetch a symbol");
138  }
139 
140 #ifndef _WIN32
141  dlerror(); // clear error message
142  void* resultRaw = dlsym(handle, functionName.c_str());
143 #endif
144 
145  if (!resultRaw)
146  {
147 #ifndef _WIN32
148  const char* error = dlerror();
149 #endif
150 
151  if (error)
152  {
153  lastError = error;
155  }
156  }
157 
158 #pragma GCC diagnostic push
159 #pragma GCC diagnostic ignored "-Wpedantic"
160  SymbolType result = (SymbolType)(resultRaw);
161 #pragma GCC diagnostic pop
162 
163  if (!result)
164  {
165  lastError = "Could not cast into desired function type";
167  }
168 
169  return result;
170 
171  }
172 }
173 
armarx::DynamicLibrary::reload
void reload()
Reloads the current library.
Definition: DynamicLibrary.cpp:131
armarx::DynamicLibraryPtr
std::shared_ptr< DynamicLibrary > DynamicLibraryPtr
Definition: DynamicLibrary.h:123
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:157
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:147
armarx::DynamicLibrary::setUnloadOnDestruct
void setUnloadOnDestruct(bool unload)
Definition: DynamicLibrary.cpp:142
armarx::DynamicLibrary::getLibraryFilename
std::filesystem::path getLibraryFilename() noexcept
Definition: DynamicLibrary.cpp:168
armarx::DynamicLibrary::DynamicLibrary
DynamicLibrary()
Definition: DynamicLibrary.cpp:29
armarx::DynamicLibrary::isLibraryLoaded
bool isLibraryLoaded() noexcept
Checks if a library is currently loaded.
Definition: DynamicLibrary.cpp:137
armarx::DynamicLibrary::getErrorMessage
std::string getErrorMessage() noexcept
Definition: DynamicLibrary.cpp:174
armarx::Logging
Base Class for all Logging classes.
Definition: Logging.h:232
armarx::DynamicLibrary::~DynamicLibrary
~DynamicLibrary() override
Definition: DynamicLibrary.cpp:37
armarx::DynamicLibrary::unload
void unload()
Unloads library.
Definition: DynamicLibrary.cpp:104
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:28
DynamicLibraryException.h