Function pointers to dlsym()'d functions in C++ without C-style casts?

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0
I'm using gtkmm's Glib::Module class, which on unix, is just a fancy wrapper around dlopen(), dlsym(), etc. Just like the dl* functions, it takes your void pointer and points it at the symbol you ask for. Well, I want to cast that back to the right function pointer type, but I can't seem to do it without using C-style casts, which everyone boos and hisses at in C++. I tried reinterpret_cast, but it told me that it can't convert between pointer-to-object and pointer-to-function. So this cast is the last non-c-plus-plussy thing left I have in my test code. Here is what I have so far:

// g++ `pkg-config glibmm-2.0 --cflags --libs` GlibModule-test.cc
#include <functional>
#include <glibmm/module.h>
#include <iostream>
using namespace std;

int main() {
Glib::Module mod("libm.so");

typedef double (*double_double_func_t)(double);

void * v = NULL;
mod.get_symbol("cos", v);
pointer_to_unary_function<double, double> cosine((double_double_func_t)v);

double test = 1.234;
cerr << "test is: " << test << endl;
cerr << "cos(test) returned: " << cosine(test) << endl;
}
 

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0
Wow, I got it!

old:
pointer_to_unary_function<double, double> cosine((double_double_func_t)v);

new:
pointer_to_unary_function<double, double> cosine(*reinterpret_cast<double_double_func_t*>(&v));

This way I'm casting between two pointers-to-objects, and then I just dereference it to get the object it points to, which is the function. I just wonder if this is sane or not. :)
 

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0
Ok I think I might be getting into some really evil stuff, but here's what I'm doing now:

template<typename TypeTo>
TypeTo void_recast(void * v) {
return *reinterpret_cast<TypeTo *>(&v);
}

....

typedef double (*double_double_func_ptr_t)(double);

void * v = NULL;
mod.get_symbol("cos", v);
pointer_to_unary_function<double, double> cosine(void_recast<double_double_func_ptr_t>(v));

It compiles with -W -Wall (all warnings turned on)...

Am I fooling myself and just giving c-style casts some fancy syntax?

edit: hell, I can even ditch the typedef now:

pointer_to_unary_function<double, double> cosine;
cosine = void_recast<pointer_to_unary_function<double, double> >(v);
 

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0
I guess what I'm doing is essentially the same as a c-style cast, and reinterpret_cast isn't meant to be used like that. So I just made a template wrapper for c-style casts called c_cast<>.

And I don't think there is any way to do this in a type-safe way, since there's no way to know what type the symbol is, since you have to get it via a void pointer. Oh well, good enough.