include/pops/runtime/dynamic/dynlib.hpp Source FileΒΆ

adc_cpp: include/pops/runtime/dynamic/dynlib.hpp Source File
adc_cpp 0.3.0
Model-free C++23 core for coupled hyperbolic-elliptic systems on adaptive (AMR) meshes, with MPI and GPU (Kokkos) backends
dynlib.hpp
Go to the documentation of this file.
1#pragma once
2
12
13#include <string>
14
15#if defined(_WIN32)
16#ifndef WIN32_LEAN_AND_MEAN
17#define WIN32_LEAN_AND_MEAN
18#endif
19#ifndef NOMINMAX
20#define NOMINMAX
21#endif
22#include <windows.h>
23#else
24#include <dlfcn.h>
25#endif
26
27namespace pops {
28namespace dynlib {
29
30#if defined(_WIN32)
31using handle = HMODULE;
32#else
33using handle = void*;
34#endif
35
37inline const char* suffix() {
38#if defined(_WIN32)
39 return ".dll";
40#elif defined(__APPLE__)
41 return ".dylib";
42#else
43 return ".so";
44#endif
45}
46
48inline handle open(const std::string& path) {
49#if defined(_WIN32)
50 // UTF-8 -> UTF-16 for LoadLibraryW (Unicode paths and paths with spaces).
51 const int n = ::MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, nullptr, 0);
52 std::wstring w(n > 0 ? n - 1 : 0, L'\0');
53 if (n > 0)
54 ::MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, w.data(), n);
55 return ::LoadLibraryW(w.c_str());
56#else
57 return ::dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
58#endif
59}
60
62inline void* sym(handle h, const char* name) {
63#if defined(_WIN32)
64 return reinterpret_cast<void*>(::GetProcAddress(h, name));
65#else
66 return ::dlsym(h, name);
67#endif
68}
69
71inline void close(handle h) {
72#if defined(_WIN32)
73 if (h)
74 ::FreeLibrary(h);
75#else
76 if (h)
77 ::dlclose(h);
78#endif
79}
80
82inline bool valid(handle h) {
83 return h != handle{};
84}
85
87inline std::string last_error() {
88#if defined(_WIN32)
89 const DWORD e = ::GetLastError();
90 if (!e)
91 return {};
92 char* buf = nullptr;
93 ::FormatMessageA(
94 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
95 nullptr, e, 0, reinterpret_cast<char*>(&buf), 0, nullptr);
96 std::string m = buf ? buf : "";
97 if (buf)
98 ::LocalFree(buf);
99 return m;
100#else
101 const char* e = ::dlerror();
102 return e ? std::string(e) : std::string();
103#endif
104}
105
106} // namespace dynlib
107} // namespace pops
bool valid(handle h)
true if h is a valid handle.
Definition dynlib.hpp:82
void * handle
Definition dynlib.hpp:33
std::string last_error()
Last error message (best-effort, for diagnostics).
Definition dynlib.hpp:87
void close(handle h)
Closes h (no-op on a null handle).
Definition dynlib.hpp:71
handle open(const std::string &path)
Opens a dynamic library (path in UTF-8). Returns a null handle on failure.
Definition dynlib.hpp:48
const char * suffix()
Platform dynamic library suffix.
Definition dynlib.hpp:37
void * sym(handle h, const char *name)
Resolves name in h. Returns nullptr if absent.
Definition dynlib.hpp:62
Definition amr_hierarchy.hpp:29