gpt4 book ai didi

c - 在编译时不知道原型(prototype)的情况下使用函数指针

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:45:27 25 4
gpt4 key购买 nike

来自 this site ,我了解到一个非常令人兴奋的事实,即您可以从共享库加载和运行代码,而无需使用它显式编译您的程序。

以下代码片段说明了如何使用 dlopen()(和相关函数)运行 C 的数学库 (libm) 中的 double cos(double) 函数:

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;

handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}

cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}

printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
}

作为一种爱好,我一直在为一种自定义语言编写一个解释器(用 C 语言),我想让用户能够选择一个共享库并从中运行代码。我知道这是可能的,因为许多语言(包括 Python 和 J,都是用 C 编写的)可以使用 dlopen() 动态调用函数,只知道在运行时将传递给函数和从函数返回什么.

但是,我无法提前预测我需要如何转换从 dlsym() 返回的 void 指针。在上面的代码中,程序员知道他们要查找的符号(“cos”)是一个使用一个 double 作为参数并返回一个 double 的函数,所以他们知道他们必须如何转换 余弦 变量为“指向接受 double 并返回 double 的函数的指针”。

如果我想编写一个用户指定文件名和函数原型(prototype)的程序,我该如何编写调用 dlsym() 并正确调用该函数的底层 C 代码?

我的理论是您需要直接从进程的堆栈中压入参数并弹出返回值(如果没有内联汇编我不知道该怎么做,我想避免这种情况),但是这由于您可能需要通过寄存器传递参数而变得复杂。有人知道如何处理吗?

最佳答案

有一个众所周知的库可以解决这个问题,被许多解释语言使用:libffi .

当然,这个库在内部使用汇编代码,但它有很多硬件和软件后端,您可以将其视为可移植解决方案

关于c - 在编译时不知道原型(prototype)的情况下使用函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47249532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com