| #if defined _WIN32 || defined __CYGWIN__ | |
| #define DLL_PUBLIC __declspec(dllexport) | |
| #else | |
| #if defined __GNUC__ | |
| #define DLL_PUBLIC __attribute__ ((visibility("default"))) | |
| #else | |
| #pragma message ("Compiler does not support symbol visibility.") | |
| #define DLL_PUBLIC | |
| #endif | |
| #endif | |
| #if defined(_WIN32) || defined(__CYGWIN__) | |
| #include <stdio.h> | |
| typedef int (*fptr) (void); | |
| #ifdef __CYGWIN__ | |
| #include <dlfcn.h> | |
| fptr find_any_f (const char *name) { | |
| return (fptr) dlsym(RTLD_DEFAULT, name); | |
| } | |
| #else /* _WIN32 */ | |
| #include <windows.h> | |
| #include <tlhelp32.h> | |
| static wchar_t* | |
| win32_get_last_error (void) | |
| { | |
| wchar_t *msg = NULL; | |
| FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| | FORMAT_MESSAGE_IGNORE_INSERTS | |
| | FORMAT_MESSAGE_FROM_SYSTEM, | |
| NULL, GetLastError (), 0, | |
| (LPWSTR) &msg, 0, NULL); | |
| return msg; | |
| } | |
| /* Unlike Linux and OS X, when a library is loaded, all the symbols aren't | |
| * loaded into a single namespace. You must fetch the symbol by iterating over | |
| * all loaded modules. Code for finding the function from any of the loaded | |
| * modules is taken from gmodule.c in glib */ | |
| fptr find_any_f (const char *name) { | |
| fptr f; | |
| HANDLE snapshot; | |
| MODULEENTRY32 me32; | |
| snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); | |
| if (snapshot == (HANDLE) -1) { | |
| wchar_t *msg = win32_get_last_error(); | |
| printf("Could not get snapshot: %S\n", msg); | |
| return 0; | |
| } | |
| me32.dwSize = sizeof (me32); | |
| f = NULL; | |
| if (Module32First (snapshot, &me32)) { | |
| do { | |
| if ((f = (fptr) GetProcAddress (me32.hModule, name)) != NULL) | |
| break; | |
| } while (Module32Next (snapshot, &me32)); | |
| } | |
| CloseHandle (snapshot); | |
| return f; | |
| } | |
| #endif | |
| int DLL_PUBLIC func(void) { | |
| fptr f; | |
| f = find_any_f ("func_from_language_runtime"); | |
| if (f != NULL) | |
| return f(); | |
| printf ("Could not find function\n"); | |
| return 1; | |
| } | |
| #else | |
| /* | |
| * Shared modules often have references to symbols that are not defined | |
| * at link time, but which will be provided from deps of the executable that | |
| * dlopens it. We need to make sure that this works, i.e. that we do | |
| * not pass -Wl,--no-undefined when linking modules. | |
| */ | |
| int func_from_language_runtime(void); | |
| int DLL_PUBLIC func(void) { | |
| return func_from_language_runtime(); | |
| } | |
| #endif |