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