可变大小自变量的C函数指针

问题描述 投票:1回答:1

我想在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;                                          
}

有没有办法在任何体系结构上都可以使之工作?

c function-pointers
1个回答
3
投票

不,没有。

它在x64上有效,因为前4个整数参数are passed in the register rcx, rdx, r8 and r9。参数实际上有多大无关紧要-它们每个都获得一个64位寄存器。仅使用寄存器的底部。由于intchar以及shortlong都是以这种方式传递的,因此您的程序将运行,并且该函数即将访问参数。

不同的体系结构传递参数的方式不同。特别是,它们可能会被压入堆栈(x86会这样做)。 charshort might在按下之前会转换为int,但是int64_t当然不会。因此,在将参数压入堆栈的32位体系结构上,调用方压入4 * 64位,并且该函数尝试读取4 * 32位,但它们未正确对齐。

甚至更糟的是,在某些调用约定中(例如x86 __stdcall),该函数必须从堆栈中删除参数。如果您对此架构的参数有误,则会破坏堆栈并导致程序崩溃。

© www.soinside.com 2019 - 2024. All rights reserved.