DynamicLibrary.cpp
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#include "DynamicLibrary.h"
26
27namespace armarx
28{
30 {
31#ifndef _WIN32
32 flags = RTLD_NOW | RTLD_GLOBAL;
33#endif
34 }
35
37 {
38 if (!unloadOnDestruct)
39 {
40 return;
41 }
42 ARMARX_WARNING << "Unloading " << libPath.string();
43 try
44 {
45 unload();
46 }
48 {
49 ARMARX_ERROR << "Error while unloading dynamic library: " << lastError;
50 }
51 }
52
53 void
54 DynamicLibrary::load(std::filesystem::path libPath)
55 {
56 if (handle)
57 {
59 "A library is already loaded. Call unload first and make sure that all references "
60 "to this library are deleted.");
61 }
62
63 // if relative and not found, check at ArmarX locations
64 if (libPath.is_relative() && !std::filesystem::exists(libPath))
65 {
66 std::string absolutePath;
67
68 if (ArmarXDataPath::getAbsolutePath(libPath.string(), absolutePath))
69 {
70 libPath = absolutePath;
71 }
72 }
73
74 if (!std::filesystem::exists(libPath))
75 {
76 throw exceptions::local::DynamicLibraryException("Lib-file not found: " +
77 libPath.string());
78 }
79
80#ifndef _WIN32
81 handle = dlopen(libPath.c_str(), flags);
82#endif
83
84
85 if (!handle)
86 {
87#ifndef _WIN32
88 const char* error = dlerror();
89#endif
90
91 if (error)
92 {
93 lastError = error;
95 }
96 else
97 {
98 throw exceptions::local::DynamicLibraryException("Unknown error");
99 }
100 }
101
102 this->libPath = libPath;
103 }
104
105 void
107 {
108 if (!handle)
109 {
110 return;
111 }
112
113 bool result = dlclose(handle) == 0;
114
115 if (!result)
116 {
117 const char* error = dlerror();
118
119 if (error)
120 {
121 lastError = error;
123 }
124 else
125 {
126 throw exceptions::local::DynamicLibraryException("Unknown error");
127 }
128 }
129
130 handle = nullptr;
131 }
132
133 void
135 {
136 unload();
137 load(libPath);
138 }
139
140 bool
142 {
143 return handle != nullptr;
144 }
145
146 void
148 {
149 this->unloadOnDestruct = unload;
150 }
151
152 void
154 {
155 flags = newFlags;
156
157 if (isLibraryLoaded())
158 {
159 reload();
160 }
161 }
162
163 std::string
165 {
166#ifdef _WIN32
167 return "dll";
168#elif __APPLE__
169 return "dylib";
170#else
171 return "so";
172#endif
173 }
174
175 std::filesystem::path
177 {
178 return libPath;
179 }
180
181 std::string
183 {
184 return lastError;
185 }
186} // namespace armarx
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
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.
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.
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
This file offers overloads of toIce() and fromIce() functions for STL container types.