我想使用 LD_PRELOAD
覆盖 libc
的 open
:
#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 8.0.1 版
。
最佳答案
试试这段代码:
originalOpen = reinterpret_cast<decltype(open) *>(dlsym(RTLD_NEXT, "open"));
当您想创建函数指针时,Decltype 获取函数的类型。从函数到其类型的指针存在隐式转换,但它们并不等同。这就是带有 decltype(original_open)
的版本完美运行的原因 - original_open
的类型是函数指针而不是函数。
关于c++ - 从类型 ‘void*’ 到函数指针的强制转换无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51474619/