从“ void *”类型到函数指针

时间:2018-07-23 08:34:04

标签: c++

我想使用openlibc覆盖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);
}

}

我使用g++ -fPIC -shared -o open.so open.cpp -ldl进行编译。

有人可以告诉我上面的代码为什么起作用,为什么会出错:

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"));

当我初始化originalOpen并注释掉该行时?

我使用了gcc version 8.0.1

1 个答案:

答案 0 :(得分:3)

尝试以下代码:

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

在要创建函数指针时,Decltype获取函数的类型。从函数到其类型的指针都有隐式强制转换,但它们并不等效。这就是使用decltype(original_open)的版本可以完美工作的原因-original_open的类型是函数指针而不是函数。