diff --git a/dynamic.c b/dynamic.c index f6d9b5fd79..1e84f2978e 100644 --- a/dynamic.c +++ b/dynamic.c @@ -337,6 +337,7 @@ static void load_symbols(enum rarch_core_type type) { RARCH_ERR("Failed to open libretro core: \"%s\"\n", settings->libretro); + RARCH_ERR("Error(s): %s\n", dylib_error()); rarch_fail(1, "load_dynamic()"); } #endif diff --git a/libretro-common/dynamic/dylib.c b/libretro-common/dynamic/dylib.c index 02d2fbecd5..4db0fea84f 100644 --- a/libretro-common/dynamic/dylib.c +++ b/libretro-common/dynamic/dylib.c @@ -31,6 +31,26 @@ #include #endif +#ifdef _WIN32 +static char last_dyn_error[512]; + +static void set_dl_error(void) +{ + DWORD err = GetLastError(); + + if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err, + MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), + last_dyn_error, + sizeof(last_dyn_error) - 1, + NULL) == 0) + snprintf(last_dyn_error, sizeof(last_dyn_error) - 1, + "unknown error %lu", err); +} +#endif + /** * dylib_load: * @path : Path to libretro core library. @@ -42,13 +62,34 @@ dylib_t dylib_load(const char *path) { #ifdef _WIN32 - dylib_t lib = LoadLibrary(path); + int prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + dylib_t lib = LoadLibrary(path); + + SetErrorMode(prevmode); + + if (!lib) + { + set_dl_error(); + return NULL; + } + last_dyn_error[0] = 0; #else dylib_t lib = dlopen(path, RTLD_LAZY); #endif return lib; } +char *dylib_error(void) +{ +#ifdef _WIN32 + if (last_dyn_error[0]) + return last_dyn_error; + return NULL; +#else + return dlerror(); +#endif +} + function_t dylib_proc(dylib_t lib, const char *proc) { function_t sym; @@ -59,6 +100,12 @@ function_t dylib_proc(dylib_t lib, const char *proc) #ifdef _WIN32 sym = (function_t)GetProcAddress(lib ? (HMODULE)lib : GetModuleHandle(NULL), proc); + if (!sym) + { + set_dl_error(); + return NULL; + } + last_dyn_error[0] = 0; #else if (lib) ptr_sym = dlsym(lib, proc); @@ -89,7 +136,9 @@ function_t dylib_proc(dylib_t lib, const char *proc) void dylib_close(dylib_t lib) { #ifdef _WIN32 - FreeLibrary((HMODULE)lib); + if (!FreeLibrary((HMODULE)lib)) + set_dl_error(); + last_dyn_error[0] = 0; #else #ifndef NO_DLCLOSE dlclose(lib); diff --git a/libretro-common/include/dynamic/dylib.h b/libretro-common/include/dynamic/dylib.h index bdfeee4988..49438b2e47 100644 --- a/libretro-common/include/dynamic/dylib.h +++ b/libretro-common/include/dynamic/dylib.h @@ -61,6 +61,8 @@ dylib_t dylib_load(const char *path); **/ void dylib_close(dylib_t lib); +char *dylib_error(void); + function_t dylib_proc(dylib_t lib, const char *proc); #endif