1
0
Files
BasaltMeter/BasaltPresenter/Presenter/dll_loader.cpp

90 lines
2.6 KiB
C++
Raw Normal View History

2025-11-27 14:15:20 +08:00
#include "dll_loader.hpp"
#include <stdexcept>
2026-01-04 23:11:58 +08:00
#include <filesystem>
#if defined(BASALT_OS_WINDOWS)
#include <windows.h>
#else
#include <unistd.h>
#endif
2025-11-27 14:15:20 +08:00
2026-01-05 16:51:58 +08:00
using ::Basalt::Shared::Char::BSStringView;
2025-11-27 14:15:20 +08:00
namespace Basalt::Presenter {
2026-01-04 23:11:58 +08:00
static std::filesystem::path get_executable() {
#if defined(BASALT_OS_WINDOWS)
wchar_t buffer[MAX_PATH];
DWORD hr = GetModuleFileNameW(NULL, buffer, MAX_PATH);
2026-01-05 16:51:58 +08:00
if (hr > 0 && hr < MAX_PATH) {
2026-01-04 23:11:58 +08:00
return std::filesystem::path(buffer);
2026-01-05 16:51:58 +08:00
} else {
throw std::runtime_error("Failed to get executable path");
2026-01-04 23:11:58 +08:00
}
#else
char buffer[PATH_MAX];
ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
if (len != -1) {
buffer[len] = '\0';
return std::filesystem::path(buffer);
} else {
throw std::runtime_error("Failed to get executable path");
}
#endif
}
2026-01-05 16:51:58 +08:00
DllLoader::DllLoader(DllKind kind, const BSStringView& filename) {
2026-01-04 23:11:58 +08:00
// Build DLL full path
auto dll_path = get_executable().parent_path();
dll_path /= BSTEXT("plugin");
switch (kind) {
case DllKind::Engine:
dll_path /= BSTEXT("engine");
break;
case DllKind::Deliver:
dll_path /= BSTEXT("deliver");
break;
case DllKind::ObjectLoader:
dll_path /= BSTEXT("object_loader");
break;
case DllKind::AnimeLoader:
dll_path /= BSTEXT("anime_loader");
break;
}
dll_path /= filename;
#if defined(BASALT_OS_WINDOWS)
dll_path.replace_extension(BSTEXT(".dll"));
2026-01-06 16:27:19 +08:00
#else
dll_path.replace_extension(BSTEXT(".so"));
2026-01-04 23:11:58 +08:00
#endif
// Load DLL
2025-11-27 14:15:20 +08:00
#if defined(BASALT_OS_WINDOWS)
2026-01-04 23:11:58 +08:00
m_Handle = LoadLibraryW(dll_path.wstring().c_str());
2025-11-27 14:15:20 +08:00
#else
2026-01-04 23:11:58 +08:00
m_Handle = dlopen(dll_path.string().c_str(), RTLD_LAZY);
2025-11-27 14:15:20 +08:00
#endif
2026-01-04 23:11:58 +08:00
// Check loaded DLL
2025-11-27 21:52:40 +08:00
if (!m_Handle) throw std::runtime_error("Can not load given dynamic library.");
2025-11-27 14:15:20 +08:00
}
DllLoader::~DllLoader() {
if (m_Handle) {
#if defined(BASALT_OS_WINDOWS)
FreeLibrary(m_Handle);
#else
dlclose(m_Handle);
#endif
}
}
2025-11-27 21:52:40 +08:00
void *DllLoader::GetFunctionPointer(const char *name) {
if (!m_Handle) throw std::runtime_error("Can not fetch function pointer on not loaded dynamic library.");
#if defined(BASALT_OS_WINDOWS)
return (void *) GetProcAddress(m_Handle, name);
#else
return (void *) dlsym(m_Handle, name);
#endif
}
2025-11-27 14:15:20 +08:00
} // namespace Basalt::Presenter