Rework ADL dynamic loader
- Use the Windows type `HMODULE` on Windows, and define a local alias to it on non-Windows. This makes the code slightly clearer about the nature of the value `handle`. - Move the `dlopen` emulation into the anonymous namespace to encourage inlining, since the wrappers are trivial name/signature compatibility functions. - Move the error reporting out of the template function, so that it is not redundantly instantiated for each type used with the template.
This commit is contained in:
parent
d9034ea609
commit
1b50c31f55
|
@ -16,41 +16,56 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
RTLD_LAZY = 1, RTLD_NOW = 2
|
RTLD_LAZY = 1, RTLD_NOW = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
void *dlopen(const char *filename, int)
|
HMODULE dlopen(const char *const filename, int)
|
||||||
{
|
{
|
||||||
return LoadLibraryA(filename);
|
return LoadLibraryA(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlclose(void *handle)
|
void dlclose(const HMODULE handle)
|
||||||
{
|
{
|
||||||
FreeLibrary(reinterpret_cast<HMODULE>(handle));
|
FreeLibrary(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dlsym(void *handle, const char *symbol)
|
void *dlsym(const HMODULE handle, const char *const symbol)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<void *>(
|
return reinterpret_cast<void *>(
|
||||||
GetProcAddress(reinterpret_cast<HMODULE>(handle), symbol));
|
GetProcAddress(handle, symbol));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
using HMODULE = void *;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static ADL_MIDIPlayer *adl_init_failure(long)
|
static ADL_MIDIPlayer *adl_init_failure(long)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F>
|
static void reported_failed_load_function(const char *const name)
|
||||||
static bool load_function(void *handle, const char *name, F *&fptr)
|
|
||||||
{
|
{
|
||||||
fptr = reinterpret_cast<F *>(dlsym(handle, name));
|
|
||||||
if (!fptr)
|
|
||||||
con_printf(CON_NORMAL, "ADLMIDI: failed to load the dynamic function \"%s\"", name);
|
con_printf(CON_NORMAL, "ADLMIDI: failed to load the dynamic function \"%s\"", name);
|
||||||
return fptr != nullptr;
|
}
|
||||||
|
|
||||||
|
template <class F>
|
||||||
|
static bool load_function(const HMODULE handle, const char *const name, F *&fptr)
|
||||||
|
{
|
||||||
|
const auto f = reinterpret_cast<F *>(dlsym(handle, name));
|
||||||
|
fptr = f;
|
||||||
|
if (!f)
|
||||||
|
/* Use out of line report function to prevent redundant instantiations
|
||||||
|
* on a per-type basis.
|
||||||
|
*/
|
||||||
|
reported_failed_load_function(name);
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ADL_MIDIPlayer *adl_init_first_call(long sample_rate)
|
static ADL_MIDIPlayer *adl_init_first_call(long sample_rate)
|
||||||
|
|
Loading…
Reference in a new issue