eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
DynLib.h
Go to the documentation of this file.
1
/*
2
** This file is part of eOn.
3
**
4
** SPDX-License-Identifier: BSD-3-Clause
5
**
6
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
#pragma once
13
16
17
#include <string>
18
19
#ifdef _WIN32
20
#ifndef WIN32_LEAN_AND_MEAN
21
#define WIN32_LEAN_AND_MEAN
22
#endif
23
#include <windows.h>
24
#else
25
#include <dlfcn.h>
26
#endif
27
28
namespace
eonc::dynlib
{
29
30
#ifdef _WIN32
31
using
Handle
= HMODULE;
32
33
inline
Handle
open
(
const
char
*name)
noexcept
{
return
LoadLibraryA(name); }
34
35
inline
void
*
sym
(
Handle
h,
const
char
*name)
noexcept
{
36
return
reinterpret_cast<
void
*
>
(GetProcAddress(h, name));
37
}
38
39
inline
void
close
(
Handle
h)
noexcept
{
40
if
(h)
41
FreeLibrary(h);
42
}
43
44
inline
std::string
error
() {
45
DWORD err = GetLastError();
46
if
(err == 0)
47
return
{};
48
LPSTR buf =
nullptr
;
49
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
50
FORMAT_MESSAGE_IGNORE_INSERTS,
51
nullptr
, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
52
reinterpret_cast<
LPSTR
>
(&buf), 0,
nullptr
);
53
std::string msg(buf ? buf :
"unknown error"
);
54
if
(buf)
55
LocalFree(buf);
56
return
msg;
57
}
58
59
#else
// POSIX (Linux, macOS)
60
using
Handle
=
void
*;
61
62
inline
Handle
open
(
const
char
*name)
noexcept
{
63
// RTLD_DEEPBIND (Linux-only): make the library prefer its own symbols over
64
// globally-visible ones. Without this, Fortran helper symbols exported by
65
// Fortran shared libraries (e.g. neighbours_ in libeon_sw.so) can be
66
// hijacked by identically-named symbols in other loaded libraries (e.g.
67
// libxtb.so.6 also exports neighbours_), causing mis-dispatch and SIGSEGV.
68
#if defined(__linux__)
69
return
dlopen(name, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
70
#else
71
return
dlopen(name, RTLD_NOW | RTLD_LOCAL);
72
#endif
73
}
74
75
inline
void
*
sym
(
Handle
h,
const
char
*name)
noexcept
{
return
dlsym(h, name); }
76
77
inline
void
close
(
Handle
h)
noexcept
{
78
if
(h)
79
dlclose(h);
80
}
81
82
inline
std::string
error
() {
83
const
char
*msg = dlerror();
84
return
msg ? std::string(msg) : std::string{};
85
}
86
#endif
87
89
inline
Handle
openFirst
(
const
char
*
const
names[])
noexcept
{
90
for
(
const
char
*
const
*name = names; *name; ++name) {
91
Handle
h =
open
(*name);
92
if
(h)
93
return
h;
94
}
95
return
{};
96
}
97
99
template
<
typename
Fn> Fn
loadSym
(
Handle
h,
const
char
*name)
noexcept
{
100
return
reinterpret_cast<
Fn
>
(
sym
(h, name));
101
}
102
103
}
// namespace eonc::dynlib
eonc::dynlib
Cross-platform dynamic library loading abstraction.
Definition
DynLib.h:28
eonc::dynlib::sym
void * sym(Handle h, const char *name) noexcept
Definition
DynLib.h:75
eonc::dynlib::Handle
void * Handle
Definition
DynLib.h:60
eonc::dynlib::error
std::string error()
Definition
DynLib.h:82
eonc::dynlib::open
Handle open(const char *name) noexcept
Definition
DynLib.h:62
eonc::dynlib::close
void close(Handle h) noexcept
Definition
DynLib.h:77
eonc::dynlib::loadSym
Fn loadSym(Handle h, const char *name) noexcept
Load a symbol and cast to a function pointer type.
Definition
DynLib.h:99
eonc::dynlib::openFirst
Handle openFirst(const char *const names[]) noexcept
Try a list of library names in order, return first successful handle.
Definition
DynLib.h:89
include
eon
DynLib.h
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf