Medical Imaging Interaction Toolkit  2016.11.0
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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include <stdexcept>
18 #include <string>
19 
20 #include "mitkTestingConfig.h"
21 
22 #if defined(__APPLE__)
23 #define PLATFORM_APPLE
24 #endif
25 
26 #if defined(unix) || defined(__unix) || defined(__APPLE__)
27 #include <dlfcn.h>
28 #define PLATFORM_UNIX
29 #elif defined(_WIN32)
30 #include <Windows.h>
31 #include <strsafe.h>
32 #define PLATFORM_WINDOWS
33 #else
34 #error Unsupported platform
35 #endif
36 
37 namespace mitk
38 {
39  class SharedLibraryHandle
40  {
41  public:
42  SharedLibraryHandle() : m_Handle(0) {}
43  SharedLibraryHandle(const std::string &name) : m_Name(name), m_Handle(0) {}
44  virtual ~SharedLibraryHandle() {}
45  void Load() { Load(m_Name); }
46  void Load(const std::string &name)
47  {
48  if (m_Handle)
49  throw std::logic_error(std::string("Library already loaded: ") + name);
50  std::string libPath = GetAbsolutePath(name);
51 #ifdef PLATFORM_UNIX
52  m_Handle = dlopen(libPath.c_str(), RTLD_LAZY | RTLD_GLOBAL);
53  if (!m_Handle)
54  {
55  const char *err = dlerror();
56  throw std::runtime_error(err ? std::string(err) : libPath);
57  }
58 #else
59  m_Handle = LoadLibrary(libPath.c_str());
60  if (!m_Handle)
61  {
62  // Retrieve the system error message for the last-error code
63  LPVOID lpMsgBuf;
64  LPVOID lpDisplayBuf;
65  DWORD dw = GetLastError();
66 
67  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
68  NULL,
69  dw,
70  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
71  (LPTSTR)&lpMsgBuf,
72  0,
73  NULL);
74 
75  // Display the error message and exit the process
76 
77  lpDisplayBuf = (LPVOID)LocalAlloc(
78  LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)libPath.c_str()) + 50) * sizeof(TCHAR));
79  StringCchPrintf((LPTSTR)lpDisplayBuf,
80  LocalSize(lpDisplayBuf) / sizeof(TCHAR),
81  TEXT("Loading %s failed with error %d: %s"),
82  libPath.c_str(),
83  dw,
84  lpMsgBuf);
85 
86  std::string errMsg((LPCTSTR)lpDisplayBuf);
87 
88  LocalFree(lpMsgBuf);
89  LocalFree(lpDisplayBuf);
90 
91  throw std::runtime_error(errMsg);
92  }
93 #endif
94 
95  m_Name = name;
96  }
97 
98  void Unload()
99  {
100  if (m_Handle)
101  {
102 #ifdef PLATFORM_UNIX
103  dlclose(m_Handle);
104 #else
105  FreeLibrary((HMODULE)m_Handle);
106 #endif
107  m_Handle = 0;
108  }
109  }
110 
111  std::string GetAbsolutePath(const std::string &name) { return GetLibraryPath() + "/" + Prefix() + name + Suffix(); }
112  std::string GetAbsolutePath() { return GetLibraryPath() + "/" + Prefix() + m_Name + Suffix(); }
113  static std::string GetLibraryPath() { return std::string(MITK_RUNTIME_OUTPUT_DIR); }
114  static std::string Suffix()
115  {
116 #ifdef PLATFORM_WINDOWS
117  return ".dll";
118 #elif defined(PLATFORM_APPLE)
119  return ".dylib";
120 #else
121  return ".so";
122 #endif
123  }
124 
125  static std::string Prefix()
126  {
127 #if defined(PLATFORM_UNIX)
128  return "lib";
129 #else
130  return "";
131 #endif
132  }
133 
134  private:
135  SharedLibraryHandle(const SharedLibraryHandle &);
136  SharedLibraryHandle &operator=(const SharedLibraryHandle &);
137 
138  std::string m_Name;
139  void *m_Handle;
140  };
141 
142 } // namespace mitk
#define MITK_RUNTIME_OUTPUT_DIR
DataCollection - Class to facilitate loading/accessing structured data.