112 lines
2.1 KiB
C++
112 lines
2.1 KiB
C++
|
|
#include "os.hpp"
|
|
|
|
#include <filesystem>
|
|
|
|
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
|
#include <mutex>
|
|
#include <dlfcn.h>
|
|
#include <pthread.h>
|
|
#elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
|
// TODO
|
|
#endif
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
namespace mijin
|
|
{
|
|
|
|
//
|
|
// internal defines
|
|
//
|
|
|
|
//
|
|
// internal constants
|
|
//
|
|
|
|
//
|
|
// internal types
|
|
//
|
|
|
|
//
|
|
// internal variables
|
|
//
|
|
|
|
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
|
namespace
|
|
{
|
|
std::mutex gDlErrorMutex; // dlerror may not be thread-safe
|
|
}
|
|
#endif // MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
|
|
|
//
|
|
// internal functions
|
|
//
|
|
|
|
//
|
|
// public functions
|
|
//
|
|
|
|
Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) noexcept
|
|
{
|
|
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
|
const std::unique_lock dlErrorLock(gDlErrorMutex);
|
|
dlerror();
|
|
|
|
const fs::path libraryPath = fs::absolute(libraryFile);
|
|
void* ptr = dlopen(libraryPath.c_str(), RTLD_NOW);
|
|
if (ptr == nullptr)
|
|
{
|
|
return ResultError(dlerror());
|
|
}
|
|
return LibraryHandle{.data = dlopen(libraryPath.c_str(), RTLD_NOW)};
|
|
#elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
|
// TODO
|
|
(void) libraryFile;
|
|
return {};
|
|
#endif
|
|
}
|
|
|
|
bool closeSharedLibrary(const LibraryHandle library) noexcept
|
|
{
|
|
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
|
return dlclose(library.data) == 0;
|
|
#elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
|
(void) library;
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName) noexcept
|
|
{
|
|
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
|
return dlsym(library.data, symbolName);
|
|
#elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
|
(void) library;
|
|
(void) symbolName;
|
|
return nullptr;
|
|
#endif
|
|
}
|
|
|
|
void setCurrentThreadName(const char* threadName) noexcept
|
|
{
|
|
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
|
pthread_setname_np(pthread_self(), threadName);
|
|
#elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
|
(void) threadName;
|
|
#endif
|
|
}
|
|
|
|
[[nodiscard]] std::string makeLibraryFilename(std::string_view libraryName) noexcept
|
|
{
|
|
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
|
return "lib" + std::string(libraryName) + ".so";
|
|
#elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
|
return std::string(libraryName) + ".dll";
|
|
#else
|
|
|
|
#endif
|
|
}
|
|
|
|
} // namespace mijin
|