我遇到的问题是我不知道如何正确进行转换,我的目标是调用将放置在 buf 中的方法。
这是我的编译器错误。
error: ‘buf’ cannot be used as a function
这是我当前的代码
...
unsigned char *getFileBuffer(const char filename[], long &fileSize)
{
...
}
void (*ptrox)(int &) = NULL;
int main()
{
long filesize = -1;
int x = 3;
//buf will consist of a operation, that takes an referenced int as an argument.
unsigned char *buf = getFileBuffer("foo", filesize);
//This is obviously not correct and does not match the description.
ptrox = (void *)&buf(int &);
ptrox(x);
cout << x;
}
这是实际的方法/缓冲区。
void i(int &x)
{
x += 2;
}
__Z1iRi:
0000000100000cbb 55 pushq %rbp
0000000100000cbc 4889e5 movq %rsp, %rbp
0000000100000cbf 48897df8 movq %rdi, -0x8(%rbp)
0000000100000cc3 488b45f8 movq -0x8(%rbp), %rax
0000000100000cc7 8b00 movl (%rax), %eax
0000000100000cc9 8d5002 leal 0x2(%rax), %edx
0000000100000ccc 488b45f8 movq -0x8(%rbp), %rax
0000000100000cd0 8910 movl %edx, (%rax)
0000000100000cd2 5d popq %rbp
0000000100000cd3 c3 ret
最佳答案
正确的类型转换应该是这样的:
ptrox = (void (*)(int &))buf;
为什么不使用dlopen
/dlsym
来加载函数?会更不容易出错。此外,默认情况下,加载函数的内存不可可执行,因此如果您尝试运行ptrox
,它将获得SIGSEGV
。
为了使用 libdl
,您需要在共享库中编译您的函数 foo
并像这样加载它:
void * libhandle = dlopen("foo.so", RTLD_NOW);
if (!libhandle) {
perror("dlopen");
abort();
}
ptrox = (void (*)(int &))dlsym(libhandle,
"foo" // C function name (use extern "C" where appropriate)
);
if (!ptrox) {
perror("dlsym");
abort();
}
如果您需要加载一个要加载的 C++ 函数指针,那么您将需要使用它的错位函数名。请查阅 nm foo.so
。
如何mmap
可执行内存:
void * getFileBuffer(const char filename[], long fileSize) {
int fd = open(filename, O_RDONLY);
if (fd < 0) {
perror("open");
abort();
}
void * buf = mmap(
NULL
, fileSize
, PROT_READ | PROT_EXEC
, MAP_PRIVATE
, fd
, 0
);
if (buf == MAP_FAILED) {
perror("map");
abort();
}
return buf;
}
关于c++ - 将 unsigned char * buffer 转换为可以接受参数的可调用 void 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22989203/