Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkTestUtilSharedLibrary.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include <stdexcept>
14 #include <string>
15 
16 #include "mitkTestingConfig.h"
17 
18 #if defined(__APPLE__)
19 #define PLATFORM_APPLE
20 #endif
21 
22 #if defined(unix) || defined(__unix) || defined(__APPLE__)
23 #include <dlfcn.h>
24 #define PLATFORM_UNIX
25 #elif defined(_WIN32)
26 #include <Windows.h>
27 #include <strsafe.h>
28 #define PLATFORM_WINDOWS
29 #else
30 #error Unsupported platform
31 #endif
32 
33 namespace mitk
34 {
35  class SharedLibraryHandle
36  {
37  public:
38  SharedLibraryHandle() : m_Handle(0) {}
39  SharedLibraryHandle(const std::string &name) : m_Name(name), m_Handle(0) {}
40  virtual ~SharedLibraryHandle() {}
41  void Load() { Load(m_Name); }
42  void Load(const std::string &name)
43  {
44  if (m_Handle)
45  throw std::logic_error(std::string("Library already loaded: ") + name);
46  std::string libPath = GetAbsolutePath(name);
47 #ifdef PLATFORM_UNIX
48  m_Handle = dlopen(libPath.c_str(), RTLD_LAZY | RTLD_GLOBAL);
49  if (!m_Handle)
50  {
51  const char *err = dlerror();
52  throw std::runtime_error(err ? std::string(err) : libPath);
53  }
54 #else
55  m_Handle = LoadLibrary(libPath.c_str());
56  if (!m_Handle)
57  {
58  // Retrieve the system error message for the last-error code
59  LPVOID lpMsgBuf;
60  LPVOID lpDisplayBuf;
61  DWORD dw = GetLastError();
62 
63  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
64  nullptr,
65  dw,
66  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
67  (LPTSTR)&lpMsgBuf,
68  0,
69  nullptr);
70 
71  // Display the error message and exit the process
72 
73  lpDisplayBuf = (LPVOID)LocalAlloc(
74  LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)libPath.c_str()) + 50) * sizeof(TCHAR));
75  StringCchPrintf((LPTSTR)lpDisplayBuf,
76  LocalSize(lpDisplayBuf) / sizeof(TCHAR),
77  TEXT("Loading %s failed with error %d: %s"),
78  libPath.c_str(),
79  dw,
80  lpMsgBuf);
81 
82  std::string errMsg((LPCTSTR)lpDisplayBuf);
83 
84  LocalFree(lpMsgBuf);
85  LocalFree(lpDisplayBuf);
86 
87  throw std::runtime_error(errMsg);
88  }
89 #endif
90 
91  m_Name = name;
92  }
93 
94  void Unload()
95  {
96  if (m_Handle)
97  {
98 #ifdef PLATFORM_UNIX
99  dlclose(m_Handle);
100 #else
101  FreeLibrary((HMODULE)m_Handle);
102 #endif
103  m_Handle = 0;
104  }
105  }
106 
107  std::string GetAbsolutePath(const std::string &name) { return GetLibraryPath() + "/" + Prefix() + name + Suffix(); }
108  std::string GetAbsolutePath() { return GetLibraryPath() + "/" + Prefix() + m_Name + Suffix(); }
109  static std::string GetLibraryPath() { return std::string(MITK_RUNTIME_OUTPUT_DIR); }
110  static std::string Suffix()
111  {
112 #ifdef PLATFORM_WINDOWS
113  return ".dll";
114 #elif defined(PLATFORM_APPLE)
115  return ".dylib";
116 #else
117  return ".so";
118 #endif
119  }
120 
121  static std::string Prefix()
122  {
123 #if defined(PLATFORM_UNIX)
124  return "lib";
125 #else
126  return "";
127 #endif
128  }
129 
130  private:
131  SharedLibraryHandle(const SharedLibraryHandle &);
132  SharedLibraryHandle &operator=(const SharedLibraryHandle &);
133 
134  std::string m_Name;
135  void *m_Handle;
136  };
137 
138 } // namespace mitk
#define MITK_RUNTIME_OUTPUT_DIR
DataCollection - Class to facilitate loading/accessing structured data.