为什么函数调用仅传递第一个参数

时间:2019-06-03 20:07:18

标签: c call

我试图仅通过强制转换调用函数(第15行),但是只有第一个参数被传递,我该如何解决?

我试图将浮点值“ 2”更改为2.0f,以声明它是浮点数而不是int,但仍然无法正常工作。

!请注意,该代码是可怕的,因为它是code golf,第15行以后必须以dll形式出现,这里的代码仅是一个测试程序,以避免多次启动目标进程。这是我的实际代码,得分为58个字符

DllMain(a,b,c){((int(*)(int,float))927309216)(‭7903472‬,2);}
#include <Windows.h>
#include <stdio.h>
char * sSkelModelStencil = "SkelModelStencil"; //here I reproduce the char like it is in the memory

void SetConsoleFloat(const char *sKey, float fVal) //this is the reproduction of SetConsoleFloat in CShell.dll
{
    printf("arg1:    %s    arg2: %f\n", sKey, fVal); //printing the arguments getting passed into the function
    return;
}

int main()
{
    while (1) {
        SetConsoleFloat("SkelModelStencil", 2); //calling the reproduction function
        ((int(*)())SetConsoleFloat)(sSkelModelStencil,2); //calling the reproduction function via a cast & using SetConsoleFloat addr
        system("PAUSE");
    }
}

2 个答案:

答案 0 :(得分:2)

在某些体系结构中,传递参数的方式取决于声明它们的方式。例如,特殊寄存器可用于float参数。重要的是函数类型的声明,而不是参数表达式的声明。

参数签名()(const char *sKey, float fVal)不同,因此传递的fVal自变量与函数期望接收的方式不同。

答案 1 :(得分:1)

首先-这是残酷的代码,请不要这样做。

第二-在编译器上打开编译器警告,以便编译器可以告诉您哪里可能出错。当然,您需要一个合适的C编译器(如果您使用的是MSVC,则不是)。 gcc会告诉您:

a.c:15:10: warning: function called through a non-compatible type

但是,要回答您的问题:您正在转换为错误的函数类型:您正在使用的函数类型为void ();但您需要void (const char*, float)。因此,尝试:

((void(*)(const char*, float))SetConsoleFloat)(sSkelModelStencil,2);

代替您现有的第15行。将转换与函数的类型定义分开也是一个好主意-为清楚起见-因此您将:

typedef  void (*scf_function_t)(const char*, float);

之前,然后:

((scf_function_t) SetConsoleFloat)(sSkelModelStencil,2);

但是再说一次-真的没有充分的理由要做这些事情。