5 * A pair of macros to simplify loading of DLL functions. Example:
7 * DECLARE_PROC_ADDR(kernel32.dll, BOOL, WINAPI, CreateHardLinkW,
8 * LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
10 * if (!INIT_PROC_ADDR(CreateHardLinkW))
11 * return error("Could not find CreateHardLinkW() function";
13 * if (!CreateHardLinkW(source, target, NULL))
14 * return error("could not create hardlink from %S to %S",
18 typedef void (*FARVOIDPROC
)(void);
21 const char *const dll
;
22 const char *const function
;
23 FARVOIDPROC pfunction
;
24 unsigned initialized
: 1;
27 /* Declares a function to be loaded dynamically from a DLL. */
28 #define DECLARE_PROC_ADDR(dll, rettype, convention, function, ...) \
29 static struct proc_addr proc_addr_##function = \
30 { #dll, #function, NULL, 0 }; \
31 typedef rettype (convention *proc_type_##function)(__VA_ARGS__); \
32 static proc_type_##function function
35 * Loads a function from a DLL (once-only).
36 * Returns non-NULL function pointer on success.
37 * Returns NULL + errno == ENOSYS on failure.
38 * This function is not thread-safe.
40 #define INIT_PROC_ADDR(function) \
41 (function = (proc_type_##function)get_proc_addr(&proc_addr_##function))
43 static inline FARVOIDPROC
get_proc_addr(struct proc_addr
*proc
)
45 /* only do this once */
46 if (!proc
->initialized
) {
48 proc
->initialized
= 1;
49 hnd
= LoadLibraryExA(proc
->dll
, NULL
,
50 LOAD_LIBRARY_SEARCH_SYSTEM32
);
52 proc
->pfunction
= (FARVOIDPROC
)GetProcAddress(hnd
,
55 /* set ENOSYS if DLL or function was not found */
58 return proc
->pfunction
;