我正在尝试对我正在开发的微控制器的解释器进行一些改进。为了执行内置函数,我目前有类似的东西(尽管更快一点):
function executeBuiltin(functionName, functionArgs) {
if (functionName=="foo") foo(getIntFromArg(functionArgs[0]));
if (functionName=="bar") bar(getIntFromArg(functionArgs[0]),getBoolFromArg(functionArgs[1]),getFloatFromArg(functionArgs[2]));
if (functionName=="baz") baz();
...
}
但它适用于资源非常有限的嵌入式设备(ARM),我需要大幅减少代码大小。我想做的是有一个通用函数来调用其他函数不同的论点- 像这样的:
function executeBuiltin(functionName, functionArgs) {
functionData = fast_lookup(functionName);
call_with_args(functionData.functionPointer, functionData.functionArgumentTypes, functionArgs);
}
因此,我希望能够调用标准 C 函数并向其传递所需的任何参数(这些参数都可以是不同的类型)。为此,我需要一个call_with_args
功能。
我想避免重写每个函数来获取 argc+argv。理想情况下,每个被调用的函数都是完全标准的 C 函数。
有一个在这里讨论这个问题 http://c-faq.com/varargs/invvarargs.19930307.html- 但自 1993 年撰写该文章以来,有什么变化吗?特别是当我在 ARM 上运行时,参数位于寄存器中而不是堆栈中。即使它不在标准 C 中,是否有任何 GCC 特定的功能可以完成?
UPDATE:看起来,尽管根据规范行为是“未定义”的,但看起来由于 C 调用的工作方式,您可以向函数传递比预期更多的参数,一切都会好起来的,因此您可以解压所有参数到一个 uint32 数组中,然后可以将每个 uint32 传递给函数。
这使得为调用编写“好的”代码变得更加容易,而且它看起来工作得很好(在 32 位平台上)。唯一的问题似乎是在传递 64 位数字并编译 64 位 x86 时,因为在这种情况下它似乎会做一些特别奇怪的事情。