Files
@ r28645:c09eac136c46
Branch filter:
Location: cpp/openttd-patchpack/source/src/library_loader.h
r28645:c09eac136c46
2.7 KiB
text/x-c
Change: Link houses production on industry chain graph by TPE_PASSENGERS or TPE_MAIL cargo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | /*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file library_loader.h Functions/types related to loading libraries dynamically. */
#ifndef LIBRARY_LOADER_H
#define LIBRARY_LOADER_H
class LibraryLoader {
public:
/**
* A function loaded from a library.
*
* Will automatically cast to the correct function pointer type on retrieval.
*/
class Function {
public:
explicit Function(void *p) : p(p) {}
template <typename T, typename = std::enable_if_t<std::is_function_v<T>>>
operator T *() const
{
return reinterpret_cast<T *>(this->p);
}
private:
void *p;
};
/**
* Load a library with the given filename.
*/
explicit LibraryLoader(const std::string &filename)
{
this->handle = this->OpenLibrary(filename);
}
/**
* Close the library.
*/
~LibraryLoader()
{
if (this->handle != nullptr) {
this->CloseLibrary();
}
}
/**
* Check whether an error occurred while loading the library or a function.
*
* @return Whether an error occurred.
*/
bool HasError()
{
return this->error.has_value();
}
/**
* Get the last error that occurred while loading the library or a function.
*
* @return The error message.
*/
std::string GetLastError()
{
return this->error.value_or("No error");
}
/**
* Get a function from a loaded library.
*
* @param symbol_name The name of the function to get.
* @return The function. Check HasError() before using.
*/
Function GetFunction(const std::string &symbol_name)
{
if (this->error.has_value()) return Function(nullptr);
return Function(this->GetSymbol(symbol_name));
}
private:
/**
* Open the library with the given filename.
*
* Should set error if any error occurred.
*
* @param filename The filename of the library to open.
*/
void *OpenLibrary(const std::string &filename);
/**
* Close the library.
*/
void CloseLibrary();
/**
* Get a symbol from the library.
*
* Should set error if any error occurred.
*
* @param symbol_name The name of the symbol to get.
*/
void *GetSymbol(const std::string &symbol_name);
std::optional<std::string> error = {}; ///< The last error that occurred, if set.
void *handle = nullptr; ///< Handle to the library.
};
#endif /* LIBRARY_LOADER_H */
|