gfactory
Loading...
Searching...
No Matches
gdl.h
Go to the documentation of this file.
1#pragma once
2
3// geomc
4#include "glogger.h"
5#include "gutilities.h"
6
7// c++ plugin loading functions
8// documentation: http://www.faqs.org/docs/Linux-mini/C++-dlopen.html
9#include <dlfcn.h>
10
11// c++
12#include <sys/stat.h> // to check if file exists
13#include <string>
14
15typedef void* dlhandle;
16
17static dlhandle load_lib(const std::string& path);
18
19static void close_lib(dlhandle handle);
20
21// exit codes: 1000s
22#define ERR_DLNOTFOUND 1001
23#define ERR_FACTORYNOTFOUND 1002
24#define ERR_DLHANDLENOTFOUND 1003
25
26
31struct DynamicLib {
32
33private:
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
43public:
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(logger), handle(nullptr) {
49 log->debug(CONSTRUCTOR, "Instantiating ", path);
50 log->debug(NORMAL, "Trying ", dlFileName);
51
52 // trying installation path + lib if not found
53 if (!doesFileExists(dlFileName)) {
54 log->debug(NORMAL, dlFileName, " not found...");
55
56 std::filesystem::path gemcRoot = gutilities::gemc_root();
57 dlFileName = gemcRoot.string() + "/lib/" + path;
58
59 log->debug(NORMAL, "Trying ", dlFileName);
60 }
61
62 // trying installation path build if not found - allows meson tests to run from the build dir
63 if (!doesFileExists(dlFileName)) {
64 log->debug(NORMAL, dlFileName, " not found...");
65
66 std::filesystem::path gemcRoot = gutilities::gemc_root();
67 dlFileName = gemcRoot.string() + "/build/" + path;
68
69 log->debug(NORMAL, "Trying ", dlFileName);
70 }
71
72 if (doesFileExists(dlFileName)) {
73 handle = load_lib(dlFileName);
74 if (handle == nullptr) {
75 char const* const dlopen_error = dlerror();
76 log->error(ERR_DLHANDLENOTFOUND, "File ", dlFileName, " found, but handle is null. Error: ",
77 dlopen_error);
78 }
79 else { log->info(0, "Loaded ", dlFileName); }
80 }
81 else { log->error(ERR_DLNOTFOUND, "could not find ", dlFileName); }
82 }
83
84 dlhandle handle = nullptr; // posix handle of the dynamic library
85
87 if (handle != nullptr) {
88 close_lib(handle);
89 log->debug(DESTRUCTOR, "Destroying ", dlFileName);
90 }
91 }
92
93
94};
95
96
97dlhandle load_lib(const std::string& lib) // never throws
98{
99 dlhandle h = nullptr;
100
101 // If the caller already supplied a path (has a slash) just try it.
102 if (lib.find('/') != std::string::npos) { h = dlopen(lib.c_str(), RTLD_NOW); }
103 else {
104 // 1. Try the file in the current working directory
105 std::string cwdPath = "./" + lib;
106 h = dlopen(cwdPath.c_str(), RTLD_NOW);
107
108 // 2. Fallback to the normal search path so LD_LIBRARY_PATH,
109 // RPATH/RUNPATH, system dirs, etc. are still honoured.
110 if (!h) { h = dlopen(lib.c_str(), RTLD_NOW); }
111 }
112 return h; // may be nullptr – caller should check and use dlerror()
113}
114
115static void close_lib(dlhandle handle) { dlclose(handle); }
void * dlhandle
Definition gdl.h:15
#define ERR_DLNOTFOUND
Definition gdl.h:22
#define ERR_DLHANDLENOTFOUND
Definition gdl.h:24
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:84
~DynamicLib()
Definition gdl.h:86
DynamicLib()=default