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:
Kp 2018-10-15 00:51:53 +00:00
parent d9034ea609
commit 1b50c31f55
1 changed files with 26 additions and 11 deletions

View File

@ -16,41 +16,56 @@
#include <windows.h>
#endif
namespace {
#if defined(_WIN32)
enum
{
RTLD_LAZY = 1, RTLD_NOW = 2
};
void *dlopen(const char *filename, int)
HMODULE dlopen(const char *const filename, int)
{
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 *>(
GetProcAddress(reinterpret_cast<HMODULE>(handle), symbol));
GetProcAddress(handle, symbol));
}
#else
using HMODULE = void *;
#endif
}
static ADL_MIDIPlayer *adl_init_failure(long)
{
return nullptr;
}
template <class F>
static bool load_function(void *handle, const char *name, F *&fptr)
static void reported_failed_load_function(const char *const name)
{
fptr = reinterpret_cast<F *>(dlsym(handle, name));
if (!fptr)
con_printf(CON_NORMAL, "ADLMIDI: failed to load the dynamic function \"%s\"", name);
return fptr != nullptr;
con_printf(CON_NORMAL, "ADLMIDI: failed to load the dynamic function \"%s\"", name);
}
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)