#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 typedef int (*fptr) (void); #ifdef __CYGWIN__ #include fptr find_any_f (const char *name) { return (fptr) dlsym(RTLD_DEFAULT, name); } #else /* _WIN32 */ #include #include 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() { 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(); int DLL_PUBLIC func(void) { return func_from_language_runtime(); } #endif