NAMD
dlloader.h
Go to the documentation of this file.
1 #ifndef DLLOADER_H
2 #define DLLOADER_H
3 
4 #include <memory>
5 #include <stdexcept>
6 #include <string>
7 
8 #if defined(WIN32) && !defined(__CYGWIN__)
9 #include "windows.h"
10 #else
11 #include <dlfcn.h>
12 #endif
13 
14 namespace dlloader {
15  template <typename T>
17  public:
18  virtual ~DLLoaderInterface() = default;
19  virtual void DLOpenLib() = 0;
20  virtual std::shared_ptr<T> DLGetInstance() = 0;
21  virtual void DLCloseLib() = 0;
22  virtual std::string LibName() const = 0;
23  };
24 #if defined (WIN32)
25  template <typename T>
26  class DLLoader: public DLLoaderInterface<T> {
27  private:
28  HMODULE mHandle;
29  std::string mPathToLib;
30  std::string mAllocClassSymbol;
31  std::string mDeleteClassSymbol;
32  public:
33  DLLoader(
34  std::string pathToLib,
35  std::string allocClassSymbol = "allocator",
36  std::string deleteClassSymbol = "deleter"):
37  mPathToLib(std::move(pathToLib)),
38  mAllocClassSymbol(std::move(allocClassSymbol)),
39  mDeleteClassSymbol(std::move(deleteClassSymbol)) {}
40  ~DLLoader() = default;
41  void DLOpenLib() override {
42  if (!(mHandle = LoadLibrary(mPathToLib.c_str()))) {
43  throw std::runtime_error(std::string{"Cannot open and load "} + mPathToLib);
44  }
45  }
46  void DLCloseLib() override {
47  if (FreeLibrary(mHandle) == 0) {
48  throw std::runtime_error(std::string{"Cannot close "} + mPathToLib);
49  }
50  }
51  std::shared_ptr<T> DLGetInstance() override {
52  using allocClass = T *(*)();
53  using deleteClass = void (*)(T *);
54  auto allocFunc = reinterpret_cast<allocClass>(dlsym(mHandle, mAllocClassSymbol.c_str()));
55  auto deleteFunc = reinterpret_cast<deleteClass>(dlsym(mHandle, mDeleteClassSymbol.c_str()));
56  if (!allocFunc || !deleteFunc) {
57  try {
58  DLCloseLib();
59  } catch (...) {
60  throw;
61  }
62  throw std::runtime_error(std::string{"Cannot find allocator or deleter symbol in "} + mPathToLib);
63  }
64  return std::shared_ptr<T>(allocFunc(), [deleteFunc](T* p){deleteFunc(p);});
65  }
66  std::string LibName() const override {
67  return mPathToLib;
68  }
69  };
70 #else
71  template <typename T>
72  class DLLoader: public DLLoaderInterface<T> {
73  private:
74  void* mHandle;
75  std::string mPathToLib;
76  std::string mAllocClassSymbol;
77  std::string mDeleteClassSymbol;
78  public:
80  std::string pathToLib,
81  std::string allocClassSymbol = "allocator",
82  std::string deleteClassSymbol = "deleter"):
83  mPathToLib(std::move(pathToLib)),
84  mAllocClassSymbol(std::move(allocClassSymbol)),
85  mDeleteClassSymbol(std::move(deleteClassSymbol)) {}
86  ~DLLoader() = default;
87  void DLOpenLib() override {
88  if (!(mHandle = dlopen(mPathToLib.c_str(), RTLD_NOW|RTLD_LAZY))) {
89  throw std::runtime_error(std::string{dlerror()});
90  }
91  }
92  void DLCloseLib() override {
93  if (dlclose(mHandle) != 0) {
94  throw std::runtime_error(std::string{dlerror()});
95  }
96  }
97  std::shared_ptr<T> DLGetInstance() override {
98  using allocClass = T *(*)();
99  using deleteClass = void (*)(T *);
100  auto allocFunc = reinterpret_cast<allocClass>(dlsym(mHandle, mAllocClassSymbol.c_str()));
101  auto deleteFunc = reinterpret_cast<deleteClass>(dlsym(mHandle, mDeleteClassSymbol.c_str()));
102  if (!allocFunc || !deleteFunc) {
103  try {
104  DLCloseLib();
105  throw std::runtime_error(std::string{dlerror()});
106  } catch (...) {
107  throw;
108  }
109  throw std::runtime_error(std::string{dlerror()});
110  }
111  return std::shared_ptr<T>(allocFunc(), [deleteFunc](T* p){deleteFunc(p);});
112  }
113  std::string LibName() const override {
114  return mPathToLib;
115  }
116  };
117 #endif
118 }
119 
120 #endif // DLLOADER_H
std::string LibName() const override
Definition: dlloader.h:113
virtual void DLCloseLib()=0
DLLoader(std::string pathToLib, std::string allocClassSymbol="allocator", std::string deleteClassSymbol="deleter")
Definition: dlloader.h:79
std::shared_ptr< T > DLGetInstance() override
Definition: dlloader.h:97
virtual ~DLLoaderInterface()=default
void DLCloseLib() override
Definition: dlloader.h:92
virtual std::shared_ptr< T > DLGetInstance()=0
virtual std::string LibName() const =0
void DLOpenLib() override
Definition: dlloader.h:87
virtual void DLOpenLib()=0