【问题标题】:C - call function with dynamic number of argumentsC - 具有动态参数数量的调用函数
【发布时间】:2015-05-31 23:43:58
【问题描述】:

我有一个带有特定数量参数的 C 函数(不是 varargs 函数)。例如:

void testfunction(int a, int b, int c);

这个函数是一个黑盒,所以我不能修改它。

在主函数中,我有一个数组,其中包含我想要传递给“testfunction”的所有参数。例如:

void main() {
    int args[] = {1, 2, 3};
    ...
}

假设我事先不知道我的“testfunction”将接受多少个参数(因为这个函数可以改变,取决于我要测试的函数),我该如何调用“testfunction”动态定义数组中的参数?

我对 Ruby 有一些经验,相当于

def test(a, b, c)
    ...
end
array = [1,2,3]
test(*array)

非常感谢!

【问题讨论】:

  • 没有标准的 C 方法可以做到这一点。您将不得不求助于特定于机器的组装技巧,或者为您想要支持的每个数量的参数设置一个长大小写开关。
  • 只要您的调用约定是 caller-cleanup,您就可以调用具有比它需要/想要的更多参数的函数。
  • 也许我遗漏了一些东西(如果是这样,对不起),但为什么您的测试函数不能接受指向数组和多个参数的指针? void testfunction(void *arrayPtr, int numArgs)?
  • 嗯,不知道_Generic会不会有帮助。
  • @Mawg 问题是“testfunction”是一个黑盒,我无法控制它,我应该可以随时更改它。或者,无论如何,我可以改变一些东西,但我需要它保持完全相同的行为方式。因此,如果我更改它的原型(例如,如您所建议的),每次更改“testfunction”时,我都必须更改对函数主体中参数的所有引用,这有点烦人。

标签: c arguments


【解决方案1】:

好吧,您无法完全实现您想要的,但是,如果您对要传输的参数数量有限制,您可以接近。您还将失去一些类型的安全性。操作方法如下:

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

typedef void (*tf_t)(); // `tf_t` can accept any number of arguments

void tf1(int a) { printf("tf1: %d\n", a); }
void tf2(int a, int b) { printf("tf2: %d, %d\n", a,b); }
void tf3(int a, int b, int c) { printf("tf3: %d, %d, %d\n", a,b,c); }

void call(tf_t tf, int args[], unsigned n)
{
    switch (n) {
    case 0: tf(); break;
    case 1: tf(args[0]); break;
    case 2: tf(args[0], args[1]); break;
    case 3: tf(args[0], args[1], args[2]); break;
    default: puts("Can't handle more than 3 arguments"); abort(); break;
    }
}

int main()
{
    int args[] = { 1, 2 };
    call(tf2, args, sizeof args / sizeof args[0]);
    return 0;
}

当然,如果您将tf3 传递给call(),它将打印垃圾作为第三个数字,但这是您付出的代价。

原则上,您不应该这样做,因为调用约定可能存在很多问题,但在实践中,它很可能会起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2012-02-02
    • 2016-02-07
    • 2010-10-15
    • 2019-12-17
    相关资源
    最近更新 更多