robert
robert

Reputation: 3726

Invalid cast from type ‘void*’ to function pointer

I want to override open from libc using LD_PRELOAD:

#include <dlfcn.h>
#include <sys/stat.h>

extern "C" {

int open(const char *path, int flags, mode_t mode)
{
    int (*originalOpen)(const char *path, int flags, mode_t mode);
    originalOpen = reinterpret_cast<decltype(originalOpen)>(dlsym(RTLD_NEXT, "open"));
    //originalOpen = reinterpret_cast<decltype(open)>(dlsym(RTLD_NEXT, "open"));
    //...
    return (*originalOpen)(path, flags, mode);
}

}

I compile with g++ -fPIC -shared -o open.so open.cpp -ldl.

Can somebody tell me why the above code works, and why I get the errror:

error: invalid cast from type ‘void*’ to type ‘int(const char*, int, mode_t)’ {aka ‘int(const char*, int, unsigned int)’}
  originalOpen = reinterpret_cast<decltype(open)>(dlsym(RTLD_NEXT, "open"));

when I initialize originalOpen with the line commented out?

I used gcc version 8.0.1.

Upvotes: 1

Views: 788

Answers (1)

bartop
bartop

Reputation: 10315

Try this code:

originalOpen = reinterpret_cast<decltype(open) *>(dlsym(RTLD_NEXT, "open"));

Decltype gets the type of the function while You want to create function pointer. There is implicit cast from function to pointer of its type but these are not equivalent. This is why version with decltype(original_open) works perfectly - type of original_open is function pointer and not the function.

Upvotes: 3

Related Questions