我试图仅通过强制转换调用函数(在第 15 行(,但只传递了第一个参数,我该如何解决它?
我试图将浮点值"2"更改为 2.0f 以声明它是浮点数而不是整数,但它仍然不起作用。
!注意代码很糟糕,因为它是代码高尔夫,第 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: %fn", 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");
}
}
在某些体系结构中,传递参数的方式取决于声明参数的方式。例如,特殊寄存器可用于float
参数。重要的是函数类型的声明,而不是参数表达式的声明。
参数签名()
与(const char *sKey, float fVal)
不同,因此fVal
参数的传递方式与函数期望接收它的方式不同。
首先 - 这是残暴的代码,不要那样做。
其次 - 在编辑器警告的情况下编译代码,以便编译器可以告诉您可能出错的地方。当然,你需要一个合适的C编译器(MSVC不是,如果你使用它的话(。海湾合作委员会会告诉你:
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);
但同样 - 首先真的没有充分的理由这样做。