调用未知参数的函数

时间:2014-12-11 21:55:16

标签: c++

我必须使用少量参数调用函数。我不知道参数的数量,但它们在计算时间方面是众所周知的。我需要存储它并转换为(void *)()但是当重新调用它时,需要使用参数调用它。我假设参数将在堆栈中。

void f(int a, int b)
{
  ...
}

(void*)() c = (void*)()f; 

...
pop param2;
pop param1;
call c;

有可能这样做吗?我需要它因为我正在寻找一种方法如何从我的解释器调用函数,并希望有一些类似于编写时间函数注册的东西,而不是直接从我的汇编程序调用它。所以我假设函数的参数将在我自己的堆栈上。我可以将它们重写为实际堆栈,然后使用此参数调用函数。

或许还有其他方法可以达到这个目的?

我正在使用GCC。

这个临时解决了我的问题,但它与理想情况相差甚远:

auto& called = ctx.Functions[funcName];
shortWord param1;
shortWord param2;
switch(called.ParametersCount)
{
    case 0:
        called.Address();
        break;
    case 1:
        param1 = ctx.Locals.top();
        ctx.Locals.pop();
        (reinterpret_cast<void (*)(void*)>(called.Address))((void*)param1);
        break;
    case 2:
        param1 = ctx.Locals.top();
        ctx.Locals.pop();
        param2 = ctx.Locals.top();
        ctx.Locals.pop();
        (reinterpret_cast<void (*)(void*, void*)>(called.Address))((void*)param1, (void*)param2);
        break;
}

void ABC(shortWord sw)
{
    shortWord tmp = sw;
    for(int i = 0; i < tmp; ++i)
    {
        std::cout<<i<<std::endl;
    }
}

1 个答案:

答案 0 :(得分:1)

在C中你必须手动执行调用约定但不是很难,请查看http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl或考虑使用libffi来帮助你。您也可以在C ++中使用libffi,但它不支持所有调用约定(例如虚拟调用或对非虚拟类函数的调用)

在C ++中你可以使用std :: bind,但是std :: bind需要一个完整的函数类型,你将无法简单地调用一个

typedef void (*n)();

您可以创建一个宏来自动定义函数和std :: function refence并将其存储在某处,这样您以后可以使用std :: bind调用它,减去定义它看起来像这样

#include <iostream>
#include <functional>
#include <stdio.h>

double d(double x, double y) { return x / y; }
std::function<double(double, double)> d_ref = d;


int main()
{
    double v1 = 10;
    double v2 = 20;

    printf("out1: %f\n", d(v1, v2));

    auto fn_d = std::bind(d_ref, v1, v2);

    printf("out2: %f\n", fn_d());

    printf("ok");
    getchar();
}