繁体   English   中英

指向可变大小参数的 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 个整数参数在寄存器 rcx、rdx、r8 和 r9 中传递 参数实际上有多大无关紧要 - 无论如何,它们每个都有一个 64 位寄存器。 仅使用寄存器的底部。 由于intchar以及shortlong都是以这种方式传递的,因此您的程序将运行并且该函数即将访问参数。

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

更糟糕的是,在某些调用约定(例如 x86 __stdcall )中,函数必须从堆栈中删除参数。 如果你在这个架构上有错误的参数,它会破坏堆栈并使你的程序崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM