Skip to content

Commit 3b6e73a

Browse files
committed
Merge branch 'js/win32-lazyload-dll'
Add a helper in anticipation for its need in a future topic RSN. * js/win32-lazyload-dll: Win32: simplify loading of DLL functions
2 parents 4da3e23 + db2f7c4 commit 3b6e73a

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

compat/win32/lazyload.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef LAZYLOAD_H
2+
#define LAZYLOAD_H
3+
4+
/*
5+
* A pair of macros to simplify loading of DLL functions. Example:
6+
*
7+
* DECLARE_PROC_ADDR(kernel32.dll, BOOL, CreateHardLinkW,
8+
* LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
9+
*
10+
* if (!INIT_PROC_ADDR(CreateHardLinkW))
11+
* return error("Could not find CreateHardLinkW() function";
12+
*
13+
* if (!CreateHardLinkW(source, target, NULL))
14+
* return error("could not create hardlink from %S to %S",
15+
* source, target);
16+
*/
17+
18+
struct proc_addr {
19+
const char *const dll;
20+
const char *const function;
21+
FARPROC pfunction;
22+
unsigned initialized : 1;
23+
};
24+
25+
/* Declares a function to be loaded dynamically from a DLL. */
26+
#define DECLARE_PROC_ADDR(dll, rettype, function, ...) \
27+
static struct proc_addr proc_addr_##function = \
28+
{ #dll, #function, NULL, 0 }; \
29+
static rettype (WINAPI *function)(__VA_ARGS__)
30+
31+
/*
32+
* Loads a function from a DLL (once-only).
33+
* Returns non-NULL function pointer on success.
34+
* Returns NULL + errno == ENOSYS on failure.
35+
* This function is not thread-safe.
36+
*/
37+
#define INIT_PROC_ADDR(function) \
38+
(function = get_proc_addr(&proc_addr_##function))
39+
40+
static inline void *get_proc_addr(struct proc_addr *proc)
41+
{
42+
/* only do this once */
43+
if (!proc->initialized) {
44+
HANDLE hnd;
45+
proc->initialized = 1;
46+
hnd = LoadLibraryExA(proc->dll, NULL,
47+
LOAD_LIBRARY_SEARCH_SYSTEM32);
48+
if (hnd)
49+
proc->pfunction = GetProcAddress(hnd, proc->function);
50+
}
51+
/* set ENOSYS if DLL or function was not found */
52+
if (!proc->pfunction)
53+
errno = ENOSYS;
54+
return proc->pfunction;
55+
}
56+
57+
#endif

0 commit comments

Comments
 (0)