aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/plugins.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/base/plugins.cpp b/base/plugins.cpp
index 25b8a7a5f8..b222fcfcc2 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -141,6 +141,9 @@ public:
#ifdef DYNAMIC_MODULES
class DynamicPlugin : public Plugin {
+protected:
+ typedef void (*VoidFunc)();
+
void *_dlHandle;
Common::String _filename;
@@ -151,7 +154,7 @@ class DynamicPlugin : public Plugin {
DetectFunc _df;
GameList _games;
- void *findSymbol(const char *symbol);
+ VoidFunc findSymbol(const char *symbol);
public:
DynamicPlugin(const Common::String &filename)
@@ -181,22 +184,29 @@ public:
void unloadPlugin();
};
-void *DynamicPlugin::findSymbol(const char *symbol) {
+DynamicPlugin::VoidFunc DynamicPlugin::findSymbol(const char *symbol) {
#if defined(UNIX) || defined(__DC__)
void *func = dlsym(_dlHandle, symbol);
if (!func)
warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror());
- return func;
#else
#if defined(_WIN32)
- void *func = (void*)GetProcAddress((HMODULE)_dlHandle, symbol);
+ void *func = (void *)GetProcAddress((HMODULE)_dlHandle, symbol);
if (!func)
warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str());
- return func;
#else
#error TODO
#endif
#endif
+
+ // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++
+ // standard and POSIX: ISO C++ disallows casting between function pointers
+ // and data pointers, but dlsym always returns a void pointer. For details,
+ // see e.g. <http://www.trilithium.com/johan/2004/12/problem-with-dlsym/>.
+ assert(sizeof(VoidFunc) == sizeof(func));
+ VoidFunc tmp;
+ memcpy(&tmp, &func, sizeof(VoidFunc));
+ return tmp;
}
bool DynamicPlugin::loadPlugin() {