| #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 |