guanaqo 1.0.0-alpha.26
Utilities for scientific software
Loading...
Searching...
No Matches
dl.cpp
Go to the documentation of this file.
1#include <guanaqo/dl.hpp>
2
3#if _WIN32
4#include <windows.h>
5#else
6#include <dlfcn.h>
7#endif
8
9#include <cassert>
10
11namespace guanaqo {
12
13#if _WIN32
14std::shared_ptr<char> get_last_error_msg() {
15 char *err = nullptr;
16 auto opt = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
17 FORMAT_MESSAGE_IGNORE_INSERTS;
18 auto lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
19 if (FormatMessage(opt, NULL, GetLastError(), lang,
20 reinterpret_cast<char *>(&err), 0, NULL) != 0) {
21 return std::shared_ptr<char>{err, [](char *e) { LocalFree(e); }};
22 } else {
23 static char msg[] = "(failed to get error message)";
24 return std::shared_ptr<char>{msg, [](char *) {}};
25 }
26}
27
28std::shared_ptr<void> load_lib(const std::filesystem::path &so_filename,
29 [[maybe_unused]] DynamicLoadFlags flags) {
30 assert(!so_filename.empty());
31 void *h = LoadLibraryW(so_filename.c_str());
32 if (!h)
33 throw dynamic_load_error("Unable to load \"" + so_filename.string() +
34 "\": " + get_last_error_msg().get());
35 return std::shared_ptr<void>{
36 h, +[](void *h) { FreeLibrary(static_cast<HMODULE>(h)); }};
37}
38
39void *load_func(void *handle, const std::string &name) {
40 assert(handle);
41 auto *h = GetProcAddress(static_cast<HMODULE>(handle), name.c_str());
42 if (!h)
43 throw dynamic_load_error("Unable to load function '" + name +
44 "': " + get_last_error_msg().get());
45 return reinterpret_cast<void *>(h);
46}
47#else
48std::shared_ptr<void> load_lib(const std::filesystem::path &so_filename,
49 DynamicLoadFlags dl_flags) {
50 assert(!so_filename.empty());
51 ::dlerror();
52 void *h = ::dlopen(so_filename.c_str(), dl_flags);
53 if (auto *err = ::dlerror())
54 throw dynamic_load_error(err);
55 return std::shared_ptr<void>{h, &::dlclose};
56}
57
58void *load_func(void *handle, const std::string &name) {
59 assert(handle);
60 ::dlerror();
61 auto *h = ::dlsym(handle, name.c_str());
62 if (auto *err = ::dlerror())
63 throw dynamic_load_error("Unable to load function '" + name +
64 "': " + err);
65 return h;
66}
67#endif
68
69} // namespace guanaqo
Dynamic library loading and symbol lookup.
void * load_func(void *lib_handle, const std::string &name)
Get a pointer to a function inside of a loaded DLL or SO file.
Definition dl.cpp:58
std::shared_ptr< void > load_lib(const std::filesystem::path &so_filename, DynamicLoadFlags flags)
Load a DLL or DSO file.
Definition dl.cpp:48
Flags to be passed to dlopen.
Definition dl-flags.hpp:13
Failed to load a DLL or SO file, or failed to access a function in it.
Definition dl.hpp:17