17#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
19#elif defined(_WIN32) || defined(_WIN64)
30 Impl() : _dll(nullptr) {}
39 catch (
const DLLException& ex)
41 fatality(DLLException(ex.string()).Attach(_path));
45 const Path path()
const {
return _path; }
49 return (_dll !=
nullptr);
52 bool IsResolve(
const std::string& name)
const
54 assert(IsLoaded() &&
"DLL must be loaded!");
58 return ResolveAddress(name) !=
nullptr;
61 void Assign(
const Path& path)
63 assert(!IsLoaded() &&
"DLL must not be loaded when assigning a new path!");
69#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
71 if (_path.IsRelative())
72 _path = Path::executable().parent().Append(_path);
76 std::string filename = _path.filename().string();
77 std::string prefix = DLL::prefix();
78 if (std::strncmp(filename.c_str(), prefix.c_str(), prefix.size()) != 0)
79 _path.ReplaceFilename(prefix + filename);
82 if (_path.extension() != DLL::extension())
83 _path.Concat(DLL::extension());
88 assert(!IsLoaded() &&
"DLL is already loaded!");
92#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
93 _dll = dlopen(_path.string().c_str(), RTLD_NOW);
94#elif defined(_WIN32) || defined(_WIN64)
95 _dll = LoadLibraryExW(_path.wstring().c_str(),
nullptr, 0);
97 return (_dll !=
nullptr);
100 bool Load(
const Path& path)
108 assert(IsLoaded() &&
"DLL is not loaded!");
112#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
113 int result = dlclose(_dll);
115 throwex DLLException(
format(
"Cannot unload DLL file: {}!", dlerror())).Attach(_path);
116#elif defined(_WIN32) || defined(_WIN64)
117 if (!FreeLibrary(_dll))
118 throwex DLLException(
"Cannot unload DLL file!").Attach(_path);
123 void* ResolveAddress(
const std::string& name)
const
125 assert(IsLoaded() &&
"DLL is not loaded!");
129#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
130 return dlsym(_dll, name.c_str());
131#elif defined(_WIN32) || defined(_WIN64)
132 return (
void*)GetProcAddress(_dll, name.c_str());
138#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
140#elif defined(_WIN32) || defined(_WIN64)
151 static_assert((StorageSize >=
sizeof(Impl)),
"DLL::StorageSize must be increased!");
152 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"DLL::StorageAlign must be adjusted!");
155 new(&_storage)Impl();
162 static_assert((StorageSize >=
sizeof(Impl)),
"DLL::StorageSize must be increased!");
163 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"DLL::StorageAlign must be adjusted!");
166 new(&_storage)Impl();
178 static_assert((StorageSize >=
sizeof(Impl)),
"DLL::StorageSize must be increased!");
179 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"DLL::StorageAlign must be adjusted!");
182 new(&_storage)Impl();
184 impl().Assign(dll.
path());
191 static_assert((StorageSize >=
sizeof(Impl)),
"DLL::StorageSize must be increased!");
192 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"DLL::StorageAlign must be adjusted!");
195 new(&_storage)Impl();
197 std::swap(_storage, dll._storage);
203 reinterpret_cast<Impl*
>(&_storage)->~Impl();
214 impl().Assign(dll.
path());
220 std::swap(_storage, dll._storage);
227bool DLL::IsResolve(
const std::string& name)
const {
return impl().IsResolve(name); }
233void* DLL::ResolveAddress(
const std::string& name)
const {
return impl().ResolveAddress(name); }
238 swap(_storage, dll._storage);
DLL & operator=(const Path &path)
friend void swap(DLL &dll1, DLL &dll2) noexcept
bool IsResolve(const std::string &name) const
Is dynamic link library resolve the given symbol?
bool Load()
Load dynamic link library.
void Unload()
Unload dynamic link library.
DLL()
Initialize the dynamic link library with an empty path.
const Path path() const
Get the dynamic link library path.
bool IsLoaded() const
Is dynamic link library loaded?
Aligned storage validator.
Dynamic link library definition.
#define throwex
Throw extended exception macro.
Fatal abort execution definition.
#define fatality(...)
Fatal abort execution extended macro.
C++ Common project definitions.
std::string format(fmt::format_string< T... > pattern, T &&... args)
Format string.
void swap(FileCache &cache1, FileCache &cache2) noexcept
Aligned storage validator definition.