diff --git a/examples/unix/main.c b/examples/unix/main.c index c59edbd..26e8c05 100644 --- a/examples/unix/main.c +++ b/examples/unix/main.c @@ -2,11 +2,12 @@ typedef void (*func_handle)(); -int main() -{ - struct hotwire_dll_t dll = hw_dlopen("./bin/exampleUnixLib.dll", RTLD_NOW); +int main() { + struct hotwire_dll_t dll = hw_dlopen("./bin/exampleUnixLib.dll", RTLD_NOW); - func_handle func = (func_handle)hw_dlsym(dll, "test"); + func_handle func = (func_handle)hw_dlsym(dll, "test"); - func(); + func(); + + hw_dlclose(dll); } \ No newline at end of file diff --git a/examples/win/main.c b/examples/win/main.c index 5ecd03f..5202d78 100644 --- a/examples/win/main.c +++ b/examples/win/main.c @@ -9,4 +9,6 @@ int main() func_handle func = (func_handle)hw_dlsym(dll, "test"); func(); + + hw_dlclose(dll); } \ No newline at end of file diff --git a/src/dlopen.c b/src/dlopen.c index c711929..9048b99 100644 --- a/src/dlopen.c +++ b/src/dlopen.c @@ -9,9 +9,9 @@ struct hotwire_dll_t hw_dlopen(const char *file, int flags) { #if defined(__linux__) || defined(__APPLE__) dll.dll_handle = dlopen(file, flags); - if (dll.dll_handle == NULL){ - printf("could not load dll(UNIX api call returned error)\n"); - printf("error message: %s\n", dlerror()); + if (dll.dll_handle == NULL) { + printf("Could not load dll(UNIX api call returned error)\n"); + printf("Error message: %s\n", dlerror()); exit(-1); } @@ -21,9 +21,9 @@ struct hotwire_dll_t hw_dlopen(const char *file, int flags) { #if defined(_WIN32) dll.dll_handle = LoadLibrary(file); - if (!dll.dll_handle){ - printf("could not load dll(windows api call returned error)\n"); - + if (!dll.dll_handle) { + printf("Could not load dll(Windows api call returned error)\n"); + hw_platform_win32_get_last_error(TEXT("LoadLibrary")); exit(-1); } #endif @@ -31,12 +31,61 @@ struct hotwire_dll_t hw_dlopen(const char *file, int flags) { return dll; } -void* hw_dlsym(struct hotwire_dll_t dll, const char* symbol){ - #if defined(_WIN32) - return GetProcAddress(dll.dll_handle, symbol); - #endif +void *hw_dlsym(struct hotwire_dll_t dll, const char *symbol) { +#if defined(_WIN32) + return GetProcAddress(dll.dll_handle, symbol); +#endif - #if defined(__linux) || defined(__APPLE__) - return dlsym(dll.dll_handle, symbol); - #endif -} \ No newline at end of file +#if defined(__linux) || defined(__APPLE__) + return dlsym(dll.dll_handle, symbol); +#endif +} + +enum hotwire_status_code hw_dlclose(struct hotwire_dll_t handle) { +#if defined(__linux) || defined(__APPLE__) + if (dlclose(handle.dll_handle) != 0) { + return Failed; + } else { + return Success; + } +#endif + +#if defined(__WIN32) + if (FreeLibrary(handle.dll_handle)) { + return Success; + } else { + return Failed; + } +#endif + + return NoPlatform; +} + +#if defined(_WIN32) +void hw_platform_win32_get_last_error(LPTSTR lpszFunction) { + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + DWORD dw = GetLastError(); + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpMsgBuf, 0, NULL); + + // Display the error message and exit the process + + lpDisplayBuf = + (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + + lstrlen((LPCTSTR)lpszFunction) + 40) * + sizeof(TCHAR)); + StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %d: %s"), lpszFunction, dw, + lpMsgBuf); + + printf("Error message: %s", (LPCTSTR)lpDisplayBuf); + + LocalFree(lpMsgBuf); + LocalFree(lpDisplayBuf); +} + +#endif \ No newline at end of file diff --git a/src/dlopen.h b/src/dlopen.h index 87b9097..2e68778 100644 --- a/src/dlopen.h +++ b/src/dlopen.h @@ -11,24 +11,32 @@ #if defined(_WIN32) #include +#include #endif +// Platform specific code functions + +#if defined(_WIN32) +void hw_platform_win32_get_last_error(LPTSTR lpszFunction); +#endif + +enum hotwire_status_code { Failed, Success, NoPlatform }; struct hotwire_dll_t { - #if defined(__linux__) || defined(__APPLE__) - void* dll_handle; - #endif +#if defined(__linux__) || defined(__APPLE__) + void *dll_handle; +#endif - #if defined(_WIN32) - HINSTANCE dll_handle; - #endif +#if defined(_WIN32) + HINSTANCE dll_handle; +#endif }; -// Function arguments are based off the dlopen() api on POSIX based operating systems -// Loads dll from library -struct hotwire_dll_t hw_dlopen(const char* file, int flags); +// Function arguments are based off the dlopen() api on POSIX based operating +// systems Loads dll from library +struct hotwire_dll_t hw_dlopen(const char *file, int flags); // Loads symbol from DLL -void* hw_dlsym(struct hotwire_dll_t dll, const char* symbol); +void *hw_dlsym(struct hotwire_dll_t dll, const char *symbol); -int hw_dlclose(void* handle); +enum hotwire_status_code hw_dlclose(struct hotwire_dll_t handle);