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 if (doesFileExists(dlFileName)) {
63 handle = load_lib(dlFileName);
64 if (handle == nullptr) {
65 char const* const dlopen_error = dlerror();
66 log->error(ERR_DLHANDLENOTFOUND, "File ", dlFileName, " found, but handle is null. Error: ",
67 dlopen_error);
68 }
69 else { log->info(0, "Loaded ", dlFileName); }
70 }
71 else { log->error(ERR_DLNOTFOUND, "could not find ", dlFileName); }
72 }
73
74 dlhandle handle = nullptr; // posix handle of the dynamic library
75
77 if (handle != nullptr) {
78 close_lib(handle);
79 log->debug(DESTRUCTOR, "Destroying ", dlFileName);
80 }
81 }
82
83
84};
85
86
87dlhandle load_lib(const std::string& lib) // never throws
88{
89 dlhandle h = nullptr;
90
91 // If the caller already supplied a path (has a slash) just try it.
92 if (lib.find('/') != std::string::npos) { h = dlopen(lib.c_str(), RTLD_NOW); }
93 else {
94 // 1. Try the file in the current working directory
95 std::string cwdPath = "./" + lib;
96 h = dlopen(cwdPath.c_str(), RTLD_NOW);
97
98 // 2. Fallback to the normal search path so LD_LIBRARY_PATH,
99 // RPATH/RUNPATH, system dirs, etc. are still honoured.
100 if (!h) { h = dlopen(lib.c_str(), RTLD_NOW); }
101 }
102 return h; // may be nullptr – caller should check and use dlerror()
103}
104
105static 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:74
~DynamicLib()
Definition gdl.h:76
DynamicLib()=default