c++ - 将 unsigned char * buffer 转换为可以接受参数的可调用 void 指针

标签 c++ c

我遇到的问题是我不知道如何正确进行转换,我的目标是调用将放置在 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/

相关文章:

c++ - 使用递归的二叉树平衡检查?

c - 只有字符串的第一个字符才会在 C 中打印

c - 将外部 C++ 源链接到我的 DLL 库

c++ - 用于树莓派的 C 语言 GPIO 编程

c++ - 从数组打印时零不显示为 0

c++ - 循环依赖和图

c++ - mac语音合成管理器,创建语音 channel 时,返回参数错误

c++ - 如何将输入作为空字符串输入?

c - 从 C 代码构建 AST

c - execvp 和读取命令参数