Freitag, 21. Oktober 2011

< dlsym(), ISO, C++, gimme a break >

Today, while trying to implement a simple class that can dynamically load new C++ classes into a running program using dlopen() and dlsym() on Ubuntu 11.04 using g++ 4.5.2, I came across this error:

algorithm.cc: In static member function ‘static algo::algorithm& algo::algorithm::load(const std::string&)’:
algorithm.cc:24:67: error: ISO C++ forbids casting between pointer-to-function and pointer-to-object

Couldn't be clearer, could it? According to ISO, there is no way you can convert a pointer-to-object into a pointer-to-function - PERIOD! But wait! We can fix that by adding four simple green lines (comments not counted):

#include "algo/algorithm.h" 
#include <assert.h> 
#define dlsym __gimme_a_break__ 
#include <dlfcn.h> 
#undef dlsym 
#include <string>

// redeclare dlsym to be a function returning a function
// pointer instead of void *
extern "C" void *(*dlsym(void *handle, const char *symbol))();

algo::algorithm &
algo::algorithm::load(const std::string &algo)
{
    // to at least get the illusion of safety...
    assert(sizeof(void *) == sizeof(void (*)()));
    std::string nm = "libalgo-" + algo + ".so";
    void *lib = dlopen(nm.c_str(), RTLD_NOW);
    assert(lib != 0);
    algo::algorithm *(*mk)() =
        reinterpret_cast<algo::algorithm *(*)()>(dlsym(lib, "make"));
    algo::algorithm *a = mk();
    assert(a != 0);
    return *a;
}   // load()


Voilà, everyone is happy again (except the language advocates maybe)...

Keine Kommentare:

Kommentar veröffentlichen