// ========================================================== // Windows: cl /W4 /EHsc reflect.cpp // Unix : g++ -Wall -rdynamic reflect.cpp -ldl // ========================================================== #include #include #include using std::string; using FunctionPointer = void (*)(void); // ------------------------ // Code for 'cl' // ------------------------ #ifdef _MSC_VER # include # define DO_EXPORT __declspec(dllexport) using ModuleHandle = HANDLE; using FunctionHandle = FARPROC; static ModuleHandle doOpen() { return(GetModuleHandle(NULL)); } static FunctionHandle getFunction(ModuleHandle theHandle, const string &name) { return(GetProcAddress((HMODULE)theHandle, name.c_str())); } static void doClose(ModuleHandle theHandle) { FreeLibrary((HMODULE)theHandle); } // ------------------------ // Code for 'g++' // ------------------------ #else # include # define DO_EXPORT using ModuleHandle = void *; using FunctionHandle = void *; static ModuleHandle doOpen() { return(dlopen(NULL, RTLD_LAZY)); } static FunctionHandle getFunction(ModuleHandle theHandle, const string &name) { return(dlsym(theHandle, name.c_str())); } static void doClose(ModuleHandle theHandle) { dlclose(theHandle); } #endif // ------------------------------------------------------------------------ // The functions to call, note that we must use: extern "C" so that // 'getFunction' will be able to locate them. // ------------------------------------------------------------------------ extern "C" { DO_EXPORT void f1(void) { std::cout << "f1\n"; } DO_EXPORT void f2(void) { std::cout << "f2\n"; } DO_EXPORT void f3(void) { std::cout << "f3\n"; } } // ------------------------ // main // ------------------------ int main() { ModuleHandle theHandle = doOpen(); if(theHandle == NULL) { std::cout << "Call to 'doOpen' failed\n"; return(1); } int i = 1; while(true) { std::ostringstream out; out << "f" << i++; FunctionPointer fp = (FunctionPointer)getFunction(theHandle, out.str()); if(!fp) break; fp(); } doClose(theHandle); }