/* dll.c - wrapper for loading modules */ /* PUBLIC DOMAIN - July 23, 2007 - Jon Mayo */ /* see: * http://msdn2.microsoft.com/en-us/library/ms686944.aspx * http://msdn2.microsoft.com/en-us/library/ms683212.aspx */ #include #include #include "dll.h" #ifdef WIN32 static void dll_show_error(const char *reason) { LPTSTR lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &lpMsgBuf, 0, NULL); if (reason) { fprintf(stderr, "%s:%s\n", reason, lpMsgBuf); } else { fprintf(stderr, "%s\n", lpMsgBuf); } LocalFree(lpMsgBuf); } /* return zero on success, non-zero on error */ int dll_open(dll_handle_t *h, const char *filename) { /* TODO: convert filename to windows text encoding */ *h = LoadLibrary(filename); if (!*h) { dll_show_error(filename); return -1; } return 0; } void dll_close(dll_handle_t h) { if (!FreeLibrary(h)) { dll_show_error("FreeLibrary()"); } } /* return NULL on error. address of exported symbol on success */ void *dll_func(dll_handle_t h, const char *name) { void *ret = GetProcAddress(h, name); if (!ret) { dll_show_error(name); } return ret; } #else static void dll_show_error(const char *reason) { const char *msg = dlerror(); if (msg) { if (reason) { fprintf(stderr, "%s:%s\n", reason, msg); } else { fprintf(stderr, "%s\n", msg); } } } /* return zero on success, non-zero on error */ int dll_open(dll_handle_t *h, const char *filename) { *h = dlopen(filename, RTLD_LOCAL | RTLD_NOW); if (!*h) { dll_show_error(filename); return -1; } return 0; } void dll_close(dll_handle_t h) { if (dlclose(h)) { dll_show_error("dlclose()"); } } /* return NULL on error. address of exported symbol on success */ void *dll_func(dll_handle_t h, const char *name) { void *ret = dlsym(h, name); if (!ret) { dll_show_error(name); return NULL; } return ret; } #endif