gfactory
gdl.h
Go to the documentation of this file.
1 #ifndef GDYNAMICLIB_H
2 #define GDYNAMICLIB_H 1
3 
4 #include "glogger.h"
5 
6 // c++ plugin loading functions
7 // documentation: http://www.faqs.org/docs/Linux-mini/C++-dlopen.html
8 #include <dlfcn.h>
9 
10 // c++
11 #include <sys/stat.h> // to check if file exists
12 #include <string>
13 #include <iostream>
14 
15 typedef void *dlhandle;
16 
17 static dlhandle load_lib(const std::string &path);
18 
19 static void close_lib(dlhandle handle);
20 
21 // exit codes: 1000s
22 #define EC__DLNOTFOUND 1001
23 #define EC__FACTORYNOTFOUND 1002
24 #define EC__DLHANDLENOTFOUND 1003
25 
26 
31 struct DynamicLib {
32 
33 private:
34  std::string dlFileName; // dynamic library file
35 
36  bool doesFileExists(const std::string &name) {
37  struct stat buffer;
38  return (stat(name.c_str(), &buffer) == 0);
39  }
40 
41  std::shared_ptr<GLogger> log;
42 
43 public:
44  // default constructor
45  DynamicLib() = default;
46 
47  // path here is the filename
48  DynamicLib(std::shared_ptr<GLogger> logger, std::string path) : dlFileName(path), log(std::move(logger)), handle(nullptr) {
49 
50  log->debug(CONSTRUCTOR, "Instantiating ", path);
51  log->debug(NORMAL, "Trying ", dlFileName);
52 
53  // trying $GEMC/lib/ + path if not found
54  if (!doesFileExists(dlFileName)) {
55  log->debug(NORMAL, dlFileName, "Not found...");
56  dlFileName = std::string(getenv("GEMC")) + "/lib/" + path;
57  log->debug(NORMAL, "Trying ", dlFileName);
58  }
59 
60  // trying $GEMC/lib64/ + path if not found
61  if (!doesFileExists(dlFileName)) {
62  log->debug(NORMAL, dlFileName, "Not found...");
63  dlFileName = std::string(getenv("GEMC")) + "/lib64/" + path;
64  log->debug(NORMAL, "Trying ", dlFileName);
65  }
66 
67  if (doesFileExists(dlFileName)) {
68  handle = load_lib(dlFileName);
69  log->info(0, "Loaded ", dlFileName);
70  if (handle == nullptr) {
71  char const *const dlopen_error = dlerror();
72  log->error(EC__DLHANDLENOTFOUND, "File ", dlFileName, " found, but handle is null. Error: ",
73  dlopen_error);
74  }
75  } else {
76  log->error(EC__DLNOTFOUND, "could not find ", dlFileName);
77  }
78  }
79 
80  dlhandle handle = nullptr; // posix handle of the dynamic library
81 
83  if (handle != nullptr) {
84  close_lib(handle);
85  log->debug(DESTRUCTOR, "Destroying ", dlFileName);
86  }
87  }
88 
89 
90 };
91 
92 
93 static dlhandle load_lib(const std::string &path) {
94 
95  return dlopen(path.data(), RTLD_NOW);
96  // get a handle to the lib, may be nullptr.
97  // RTLD_NOW ensures that all the symbols are resolved immediately:
98  // if a symbol cannot be found, the program will crash now instead of later.
99 }
100 
101 static void close_lib(dlhandle handle) {
102  dlclose(handle);
103 }
104 
105 #endif
void * dlhandle
Definition: gdl.h:15
#define EC__DLHANDLENOTFOUND
Definition: gdl.h:24
#define EC__DLNOTFOUND
Definition: gdl.h:22
Structure to load dynamically symbols from a shared library.
Definition: gdl.h:31
DynamicLib(std::shared_ptr< GLogger > logger, std::string path)
Definition: gdl.h:48
dlhandle handle
Definition: gdl.h:80
~DynamicLib()
Definition: gdl.h:82
DynamicLib()=default