From de4ebfb1520d30260d606f3df3a6a86b2a405c88 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 10 Jan 2017 23:14:20 +0100 Subject: [PATCH] Win32: simplify loading of DLL functions Dynamic loading of DLL functions is duplicated in several places. Add a set of macros to simplify the process. Signed-off-by: Karsten Blees Signed-off-by: Johannes Schindelin --- compat/win32.h | 2 ++ compat/win32/lazyload.h | 43 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 compat/win32/lazyload.h diff --git a/compat/win32.h b/compat/win32.h index a97e880757..4a0ccb8075 100644 --- a/compat/win32.h +++ b/compat/win32.h @@ -6,6 +6,8 @@ #include #endif +#include "compat/win32/lazyload.h" + static inline int file_attr_to_st_mode (DWORD attr) { int fMode = S_IREAD; diff --git a/compat/win32/lazyload.h b/compat/win32/lazyload.h new file mode 100644 index 0000000000..9d1a055502 --- /dev/null +++ b/compat/win32/lazyload.h @@ -0,0 +1,43 @@ +#ifndef LAZYLOAD_H +#define LAZYLOAD_H + +/* simplify loading of DLL functions */ + +struct proc_addr { + const char *const dll; + const char *const function; + FARPROC pfunction; + unsigned initialized : 1; +}; + +/* Declares a function to be loaded dynamically from a DLL. */ +#define DECLARE_PROC_ADDR(dll, rettype, function, ...) \ + static struct proc_addr proc_addr_##function = \ + { #dll, #function, NULL, 0 }; \ + static rettype (WINAPI *function)(__VA_ARGS__) + +/* + * Loads a function from a DLL (once-only). + * Returns non-NULL function pointer on success. + * Returns NULL + errno == ENOSYS on failure. + */ +#define INIT_PROC_ADDR(function) (function = get_proc_addr(&proc_addr_##function)) + +static inline void *get_proc_addr(struct proc_addr *proc) +{ + /* only do this once */ + if (!proc->initialized) { + HANDLE hnd; + proc->initialized = 1; + hnd = LoadLibraryExA(proc->dll, NULL, + LOAD_LIBRARY_SEARCH_SYSTEM32); + if (hnd) + proc->pfunction = GetProcAddress(hnd, proc->function); + } + /* set ENOSYS if DLL or function was not found */ + if (!proc->pfunction) + errno = ENOSYS; + return proc->pfunction; +} + +#endif