指向可变大小参数的 C 函数指针

C function pointer to variable size arguments

我想在 C 中有一个通用函数指针,它只指定参数的数量,但它们的大小应该是任何类型。我以为下面的程序会崩溃,但不知何故,它确实可以在某些具有 64 位架构但不适用于 32 位架构的设备上运行。我不确定架构的广泛性是否是导致不同结果的原因。

#include <stdio.h>                                         
#include <stdlib.h>                                                                                                   
typedef int METHOD(int64_t, int64_t, int64_t, int64_t);    
int foo(int i, char c, short s, long l){                           
    printf("i: %d, c: %c s: %hd l:%ld\n", i, c, s, l);         
    return 5;                                          
}                                                                                                                     
int main(int argc, char ** argv){                                  
    METHOD * ptr=(METHOD*)&foo;                                
    printf("res: %d\n", 
    ptr(1,'2',3,4));                       
    printf("res: %d\n", 
    foo(1,'2',3,4));                       
    return 0;                                          
}

有没有办法让它在任何架构上都能工作?

没有,没有。

它适用于 x64,因为前 4 个整数参数 are passed in the register rcx, rdx, r8 and r9。参数实际上有多大并不重要——无论如何,它们每个都获得一个 64 位寄存器。仅使用寄存器的底部。由于intcharshortlong都是这样传递的,所以你的程序运行,函数即将访问参数

不同的架构传递参数的方式不同。特别是,它们可能会被压入堆栈(x86 就是这样做的)。 charshort在push之前可能会转化为int,但是int64_t肯定不会。因此,在将参数压入堆栈的 32 位架构上,调用者压入 4*64 位,函数尝试读取 4*32 位,但它们没有正确排列。

更糟糕的是,在某些调用约定(例如 x86 __stdcall)中,函数必须从堆栈中删除参数。如果您对该体系结构有错误的论点,它会破坏堆栈并使您的程序崩溃。