1 #if defined _WIN32 || defined __CYGWIN__
2 #define DLL_PUBLIC __declspec(dllexport)
3 #else
4 #if defined __GNUC__
5 #define DLL_PUBLIC __attribute__ ((visibility("default")))
6 #else
7 #pragma message ("Compiler does not support symbol visibility.")
8 #define DLL_PUBLIC
9 #endif
10 #endif
11
12 #if defined(_WIN32) || defined(__CYGWIN__)
13
14 #include <stdio.h>
15
16 typedef int (*fptr) (void);
17
18 #ifdef __CYGWIN__
19
20 #include <dlfcn.h>
21
find_any_f(const char * name)22 fptr find_any_f (const char *name) {
23 return (fptr) dlsym(RTLD_DEFAULT, name);
24 }
25 #else /* _WIN32 */
26
27 #include <windows.h>
28 #include <tlhelp32.h>
29
30 static wchar_t*
win32_get_last_error(void)31 win32_get_last_error (void)
32 {
33 wchar_t *msg = NULL;
34
35 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
36 | FORMAT_MESSAGE_IGNORE_INSERTS
37 | FORMAT_MESSAGE_FROM_SYSTEM,
38 NULL, GetLastError (), 0,
39 (LPWSTR) &msg, 0, NULL);
40 return msg;
41 }
42
43 /* Unlike Linux and OS X, when a library is loaded, all the symbols aren't
44 * loaded into a single namespace. You must fetch the symbol by iterating over
45 * all loaded modules. Code for finding the function from any of the loaded
46 * modules is taken from gmodule.c in glib */
find_any_f(const char * name)47 fptr find_any_f (const char *name) {
48 fptr f;
49 HANDLE snapshot;
50 MODULEENTRY32 me32;
51
52 snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
53 if (snapshot == (HANDLE) -1) {
54 wchar_t *msg = win32_get_last_error();
55 printf("Could not get snapshot: %S\n", msg);
56 return 0;
57 }
58
59 me32.dwSize = sizeof (me32);
60
61 f = NULL;
62 if (Module32First (snapshot, &me32)) {
63 do {
64 if ((f = (fptr) GetProcAddress (me32.hModule, name)) != NULL)
65 break;
66 } while (Module32Next (snapshot, &me32));
67 }
68
69 CloseHandle (snapshot);
70 return f;
71 }
72 #endif
73
func(void)74 int DLL_PUBLIC func(void) {
75 fptr f;
76
77 f = find_any_f ("func_from_language_runtime");
78 if (f != NULL)
79 return f();
80 printf ("Could not find function\n");
81 return 1;
82 }
83
84 #else
85 /*
86 * Shared modules often have references to symbols that are not defined
87 * at link time, but which will be provided from deps of the executable that
88 * dlopens it. We need to make sure that this works, i.e. that we do
89 * not pass -Wl,--no-undefined when linking modules.
90 */
91 int func_from_language_runtime(void);
92
func(void)93 int DLL_PUBLIC func(void) {
94 return func_from_language_runtime();
95 }
96 #endif
97