aboutsummaryrefslogtreecommitdiff
path: root/win32/lazyload.h
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-01-04 12:29:19 +0000
committerRon Yorston <rmy@pobox.com>2019-01-04 15:06:26 +0000
commit0ffd8b3261e764179572d58179ae8e2c21635220 (patch)
tree29b297fe574d2d31564112a8c75becb3fb1d8464 /win32/lazyload.h
parent6b6c55e16f121976334b857a646d82c2fec0a07b (diff)
downloadbusybox-w32-0ffd8b3261e764179572d58179ae8e2c21635220.tar.gz
busybox-w32-0ffd8b3261e764179572d58179ae8e2c21635220.tar.bz2
busybox-w32-0ffd8b3261e764179572d58179ae8e2c21635220.zip
win32: reduce static storage needed for lazy loading
Only the generic function pointer and initialisation flag need to be in static storage. The DLL and function names and the specialised function pointer can be local.
Diffstat (limited to 'win32/lazyload.h')
-rw-r--r--win32/lazyload.h26
1 files changed, 11 insertions, 15 deletions
diff --git a/win32/lazyload.h b/win32/lazyload.h
index 9d1a05550..a9fcff209 100644
--- a/win32/lazyload.h
+++ b/win32/lazyload.h
@@ -4,35 +4,31 @@
4/* simplify loading of DLL functions */ 4/* simplify loading of DLL functions */
5 5
6struct proc_addr { 6struct proc_addr {
7 const char *const dll;
8 const char *const function;
9 FARPROC pfunction; 7 FARPROC pfunction;
10 unsigned initialized : 1; 8 unsigned initialized;
11}; 9};
12 10
13/* Declares a function to be loaded dynamically from a DLL. */ 11/* Declares a function to be loaded dynamically from a DLL. */
14#define DECLARE_PROC_ADDR(dll, rettype, function, ...) \ 12#define DECLARE_PROC_ADDR(rettype, function, ...) \
15 static struct proc_addr proc_addr_##function = \ 13 static struct proc_addr proc_addr_##function = { NULL, 0 }; \
16 { #dll, #function, NULL, 0 }; \ 14 rettype (WINAPI *function)(__VA_ARGS__)
17 static rettype (WINAPI *function)(__VA_ARGS__)
18 15
19/* 16/*
20 * Loads a function from a DLL (once-only). 17 * Loads a function from a DLL (once-only).
21 * Returns non-NULL function pointer on success. 18 * Returns non-NULL function pointer on success.
22 * Returns NULL + errno == ENOSYS on failure. 19 * Returns NULL and sets errno == ENOSYS on failure.
23 */ 20 */
24#define INIT_PROC_ADDR(function) (function = get_proc_addr(&proc_addr_##function)) 21#define INIT_PROC_ADDR(dll, function) \
22 (function = get_proc_addr(#dll, #function, &proc_addr_##function))
25 23
26static inline void *get_proc_addr(struct proc_addr *proc) 24static inline void *get_proc_addr(const char *dll, const char *function, struct proc_addr *proc)
27{ 25{
28 /* only do this once */ 26 /* only do this once */
29 if (!proc->initialized) { 27 if (!proc->initialized) {
30 HANDLE hnd; 28 HANDLE hnd = LoadLibraryExA(dll, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
31 proc->initialized = 1;
32 hnd = LoadLibraryExA(proc->dll, NULL,
33 LOAD_LIBRARY_SEARCH_SYSTEM32);
34 if (hnd) 29 if (hnd)
35 proc->pfunction = GetProcAddress(hnd, proc->function); 30 proc->pfunction = GetProcAddress(hnd, function);
31 proc->initialized = 1;
36 } 32 }
37 /* set ENOSYS if DLL or function was not found */ 33 /* set ENOSYS if DLL or function was not found */
38 if (!proc->pfunction) 34 if (!proc->pfunction)