mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 14:08:37 +00:00
Improve DYNAMIC_IMPORT
Don't call get_proc_address every time if if failed. Also rename Utilities/dynamic_library.h to util/dyn_lib.hpp
This commit is contained in:
parent
cdaa8cb5c4
commit
bd5253047b
7 changed files with 27 additions and 23 deletions
|
|
@ -1,69 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "dynamic_library.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
namespace utils
|
||||
{
|
||||
dynamic_library::dynamic_library(const std::string& path)
|
||||
{
|
||||
load(path);
|
||||
}
|
||||
|
||||
dynamic_library::~dynamic_library()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool dynamic_library::load(const std::string& path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
m_handle = LoadLibraryA(path.c_str());
|
||||
#else
|
||||
m_handle = dlopen(path.c_str(), RTLD_LAZY);
|
||||
#endif
|
||||
return loaded();
|
||||
}
|
||||
|
||||
void dynamic_library::close()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(reinterpret_cast<HMODULE>(m_handle));
|
||||
#else
|
||||
dlclose(m_handle);
|
||||
#endif
|
||||
m_handle = nullptr;
|
||||
}
|
||||
|
||||
void* dynamic_library::get_impl(const std::string& name) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return reinterpret_cast<void*>(GetProcAddress(reinterpret_cast<HMODULE>(m_handle), name.c_str()));
|
||||
#else
|
||||
return dlsym(m_handle, name.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
bool dynamic_library::loaded() const
|
||||
{
|
||||
return m_handle != nullptr;
|
||||
}
|
||||
|
||||
dynamic_library::operator bool() const
|
||||
{
|
||||
return loaded();
|
||||
}
|
||||
|
||||
void* get_proc_address(const char* lib, const char* name)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return reinterpret_cast<void*>(GetProcAddress(GetModuleHandleA(lib), name));
|
||||
#else
|
||||
return dlsym(dlopen(lib, RTLD_NOLOAD), name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class dynamic_library
|
||||
{
|
||||
void* m_handle = nullptr;
|
||||
|
||||
public:
|
||||
dynamic_library() = default;
|
||||
dynamic_library(const std::string& path);
|
||||
|
||||
~dynamic_library();
|
||||
|
||||
bool load(const std::string& path);
|
||||
void close();
|
||||
|
||||
private:
|
||||
void* get_impl(const std::string& name) const;
|
||||
|
||||
public:
|
||||
template <typename Type = void>
|
||||
Type* get(const std::string& name) const
|
||||
{
|
||||
Type* result;
|
||||
*reinterpret_cast<void**>(&result) = get_impl(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
bool get(Type*& function, const std::string& name) const
|
||||
{
|
||||
*reinterpret_cast<void**>(&function) = get_impl(name);
|
||||
|
||||
return function != nullptr;
|
||||
}
|
||||
|
||||
bool loaded() const;
|
||||
explicit operator bool() const;
|
||||
};
|
||||
|
||||
// (assume the lib is always loaded)
|
||||
void* get_proc_address(const char* lib, const char* name);
|
||||
|
||||
template <typename F>
|
||||
struct dynamic_import
|
||||
{
|
||||
static_assert(sizeof(F) == 0, "Invalid function type");
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct dynamic_import<R(Args...)>
|
||||
{
|
||||
R (*ptr)(Args...);
|
||||
const char* const lib;
|
||||
const char* const name;
|
||||
|
||||
// Constant initialization
|
||||
constexpr dynamic_import(const char* lib, const char* name)
|
||||
: ptr(nullptr)
|
||||
, lib(lib)
|
||||
, name(name)
|
||||
{
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
if (!ptr)
|
||||
{
|
||||
// TODO: atomic
|
||||
ptr = reinterpret_cast<R (*)(Args...)>(get_proc_address(lib, name));
|
||||
}
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
init();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Caller
|
||||
R operator()(Args... args)
|
||||
{
|
||||
init();
|
||||
|
||||
return ptr(args...);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define DYNAMIC_IMPORT(lib, name, ...) inline utils::dynamic_import<__VA_ARGS__> name(lib, #name);
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "types.h"
|
||||
#include "util/atomic.hpp"
|
||||
#include "dynamic_library.h"
|
||||
#include "util/dyn_lib.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue