这基本上就是问题所在。
void call_function(void* func, const char* funcdecl, void* arguments) {
// how do I do this?
// some pseudo code
for(i = 0; i < numargs; ++i) {
if(funcdecl.args[i].type == TYPE_DOUBLE) {
push funcdecl.args[i].doubleValue
}
...
}
call func
reslut.type = funcdecl.result_type;
if(funcdecl.result_type == TYPE) {
result.value = read_doulbe_from_stack();
}
}
// nothing from here on is known before call_function.
double foobar(int a, int b, int c) {
return a * 0.1 + b * 0.3 + c * 0.2;
}
typedef struct MyArgumentsStruct {
int a;
int b;
int c;
} MyArgumentsStruct;
int main() {
MyArgumentsStruct arguments;
call_function( (void*)(foobar), "double foobar(int a, int b, int c);", &arguments);
}
所以基本上我不能将void*
强制转换为函数类型,因为我不知道它。
我已经查找了gcc在编译为asm时所做的事情。当我正确理解它时,它会生成许多push
指令来推送堆栈上的所有函数参数,然后使用call
转到函数。然后该函数知道如何从堆栈中获取参数并将结果推回。
所以我的问题是,如何将参数从手动推送到堆栈? 我如何从堆栈中读取返回值?
答案 0 :(得分:0)
如果您只想解决问题,请选择libffi
之类的库(请参阅@SteveSummit链接的问题)。
如果您想了解它是如何完成的,您需要掌握装配。首先通过选择单个体系结构,单个调用约定,无参数来简化问题,稍后将解析C函数声明等等。只要您设法成功完成最简单的函数调用,就可以继续研究其余的细节 - 有很多!