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