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
38namespace 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
void setUnloadOnDestruct(bool unload)
std::string getErrorMessage() noexcept
std::filesystem::path getLibraryFilename() noexcept
void unload()
Unloads library.
void load(std::filesystem::path libPath)
Loads a shared library from the specified path.
SymbolType getSymbol(const std::string &functionName)
Retrieves a symbol (mostly a function) from the loaded library.
bool isLibraryLoaded() noexcept
Checks if a library is currently loaded.
void setFlags(int newFlags)
Sets the shared library opening flags and reloads the library, if a library is already loaded.
static std::string GetSharedLibraryFileExtension()
void reload()
Reloads the current library.
This exception is thrown if an invalid value was specified for a property.
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< DynamicLibrary > DynamicLibraryPtr