Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
usSharedLibrary.cpp
Go to the documentation of this file.
1 /*=============================================================================
2 
3  Library: CppMicroServices
4 
5  Copyright (c) German Cancer Research Center,
6  Division of Medical and Biological Informatics
7 
8  Licensed under the Apache License, Version 2.0 (the "License");
9  you may not use this file except in compliance with the License.
10  You may obtain a copy of the License at
11 
12  http://www.apache.org/licenses/LICENSE-2.0
13 
14  Unless required by applicable law or agreed to in writing, software
15  distributed under the License is distributed on an "AS IS" BASIS,
16  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  See the License for the specific language governing permissions and
18  limitations under the License.
19 
20 =============================================================================*/
21 
22 #include "usSharedLibrary.h"
23 
24 #include <stdexcept>
25 
26 #include <usUtils_p.h>
27 #include <usModuleRegistry.h>
28 #include <usModuleActivator.h>
29 
30 
31 #if defined(US_PLATFORM_POSIX)
32  #include <dlfcn.h>
33 #elif defined(US_PLATFORM_WINDOWS)
34  #ifndef WIN32_LEAN_AND_MEAN
35  #define WIN32_LEAN_AND_MEAN
36  #endif
37  #include <windows.h>
38  #include <strsafe.h>
39 #else
40  #error Unsupported platform
41 #endif
42 
43 
44 US_BEGIN_NAMESPACE
45 
46 #ifdef US_PLATFORM_POSIX
47 static const char PATH_SEPARATOR = '/';
48 #else
49 static const char PATH_SEPARATOR = '\\';
50 #endif
51 
52 class SharedLibraryPrivate : public SharedData
53 {
54 public:
55 
56  SharedLibraryPrivate()
57  : m_Handle(NULL)
58  #ifdef US_PLATFORM_WINDOWS
59  , m_Suffix(".dll")
60  #elif defined(US_PLATFORM_APPLE)
61  , m_Suffix(".dylib")
62  , m_Prefix("lib")
63  #else
64  , m_Suffix(".so")
65  , m_Prefix("lib")
66  #endif
67  {}
68 
69  void* m_Handle;
70 
71  std::string m_Name;
72  std::string m_Path;
73  std::string m_FilePath;
74  std::string m_Suffix;
75  std::string m_Prefix;
76 
77 };
78 
79 SharedLibrary::SharedLibrary()
80  : d(new SharedLibraryPrivate)
81 {
82 }
83 
85  : d(other.d)
86 {
87 }
88 
89 SharedLibrary::SharedLibrary(const std::string& libPath, const std::string& name)
90  : d(new SharedLibraryPrivate)
91 {
92  d->m_Name = name;
93  d->m_Path = libPath;
94 }
95 
96 SharedLibrary::SharedLibrary(const std::string& absoluteFilePath)
97  : d(new SharedLibraryPrivate)
98 {
99  d->m_FilePath = absoluteFilePath;
100  SetFilePath(absoluteFilePath);
101 }
102 
104 {
105 }
106 
108 {
109  d = other.d;
110  return *this;
111 }
112 
113 void SharedLibrary::Load(int flags)
114 {
115  if (d->m_Handle) throw std::logic_error(std::string("Library already loaded: ") + GetFilePath());
116  std::string libPath = GetFilePath();
117 #ifdef US_PLATFORM_POSIX
118  d->m_Handle = dlopen(libPath.c_str(), flags);
119  if (!d->m_Handle)
120  {
121  const char* err = dlerror();
122  throw std::runtime_error(err ? std::string(err) : (std::string("Error loading ") + libPath));
123  }
124 #else
125  d->m_Handle = LoadLibrary(libPath.c_str());
126  if (!d->m_Handle)
127  {
128  std::string errMsg = "Loading ";
129  errMsg.append(libPath).append("failed with error: ").append(GetLastErrorStr());
130 
131  throw std::runtime_error(errMsg);
132  }
133 #endif
134 }
135 
137 {
138 #ifdef US_PLATFORM_POSIX
139 #ifdef US_GCC_RTTI_WORKAROUND_NEEDED
140  Load(RTLD_LAZY | RTLD_GLOBAL);
141 #else
142  Load(RTLD_LAZY | RTLD_LOCAL);
143 #endif
144 #else
145  Load(0);
146 #endif
147 }
148 
150 {
151  if (d->m_Handle)
152  {
153 #ifdef US_PLATFORM_POSIX
154  if (dlclose(d->m_Handle))
155  {
156  const char* err = dlerror();
157  throw std::runtime_error(err ? std::string(err) : (std::string("Error unloading ") + GetLibraryPath()));
158  }
159 #else
160  if (!FreeLibrary((HMODULE)d->m_Handle))
161  {
162  std::string errMsg = "Unloading ";
163  errMsg.append(GetLibraryPath()).append("failed with error: ").append(GetLastErrorStr());
164 
165  throw std::runtime_error(errMsg);
166  }
167 #endif
168  d->m_Handle = 0;
169  }
170 }
171 
172 void SharedLibrary::SetName(const std::string& name)
173 {
174  if (IsLoaded() || !d->m_FilePath.empty()) return;
175  d.Detach();
176  d->m_Name = name;
177 }
178 
179 std::string SharedLibrary::GetName() const
180 {
181  return d->m_Name;
182 }
183 
184 std::string SharedLibrary::GetFilePath(const std::string& name) const
185 {
186  if (!d->m_FilePath.empty()) return d->m_FilePath;
187  return GetLibraryPath() + PATH_SEPARATOR + GetPrefix() + name + GetSuffix();
188 }
189 
190 void SharedLibrary::SetFilePath(const std::string& absoluteFilePath)
191 {
192  if (IsLoaded()) return;
193 
194  d.Detach();
195  d->m_FilePath = absoluteFilePath;
196 
197  std::string name = d->m_FilePath;
198  std::size_t pos = d->m_FilePath.find_last_of(PATH_SEPARATOR);
199  if (pos != std::string::npos)
200  {
201  d->m_Path = d->m_FilePath.substr(0, pos);
202  name = d->m_FilePath.substr(pos+1);
203  }
204  else
205  {
206  d->m_Path.clear();
207  }
208 
209  if (name.size() >= d->m_Prefix.size() &&
210  name.compare(0, d->m_Prefix.size(), d->m_Prefix) == 0)
211  {
212  name = name.substr(d->m_Prefix.size());
213  }
214  if (name.size() >= d->m_Suffix.size() &&
215  name.compare(name.size()-d->m_Suffix.size(), d->m_Suffix.size(), d->m_Suffix) == 0)
216  {
217  name = name.substr(0, name.size()-d->m_Suffix.size());
218  }
219  d->m_Name = name;
220 }
221 
222 std::string SharedLibrary::GetFilePath() const
223 {
224  return GetFilePath(d->m_Name);
225 }
226 
227 void SharedLibrary::SetLibraryPath(const std::string& path)
228 {
229  if (IsLoaded() || !d->m_FilePath.empty()) return;
230  d.Detach();
231  d->m_Path = path;
232 }
233 
234 std::string SharedLibrary::GetLibraryPath() const
235 {
236  return d->m_Path;
237 }
238 
239 void SharedLibrary::SetSuffix(const std::string& suffix)
240 {
241  if (IsLoaded() || !d->m_FilePath.empty()) return;
242  d.Detach();
243  d->m_Suffix = suffix;
244 }
245 
246 std::string SharedLibrary::GetSuffix() const
247 {
248  return d->m_Suffix;
249 }
250 
251 void SharedLibrary::SetPrefix(const std::string& prefix)
252 {
253  if (IsLoaded() || !d->m_FilePath.empty()) return;
254  d.Detach();
255  d->m_Prefix = prefix;
256 }
257 
258 std::string SharedLibrary::GetPrefix() const
259 {
260  return d->m_Prefix;
261 }
262 
264 {
265  return d->m_Handle;
266 }
267 
269 {
270  return d->m_Handle != NULL;
271 }
272 
273 US_END_NAMESPACE
std::string GetLibraryPath() const
void SetLibraryPath(const std::string &path)
void * GetHandle() const
void SetName(const std::string &name)
SharedLibrary & operator=(const SharedLibrary &other)
void SetPrefix(const std::string &prefix)
void SetFilePath(const std::string &absoluteFilePath)
std::string GetSuffix() const
std::string GetPrefix() const
bool IsLoaded() const
std::string GetName() const
void SetSuffix(const std::string &suffix)
static const char PATH_SEPARATOR
std::string GetLastErrorStr()
Definition: usUtils.cpp:234
std::string GetFilePath() const