C 动态库函数转换

C 动态库函数转换,c,dll,shared-libraries,dynamic-library,C,Dll,Shared Libraries,Dynamic Library,关于共享库的一个新手问题:在C中,加载动态库时,我们先使用dlopen,然后使用dlsym来查找符号或函数。现在,假设我们在dll中查找的函数类型为: int add(int a, int b); 但是如果我们把它换成另一种类型 typedef int (*sum)(int a, int b, int c); 会发生什么?C运行时会对此抱怨吗 谢谢 长话短说,这是未定义的行为。在C中调用参数数目错误的函数(即使没有dlopen/dlfree,也可以通过强制转换函数指针来实现)会产生未定义的行

关于共享库的一个新手问题:在C中,加载动态库时,我们先使用dlopen,然后使用dlsym来查找符号或函数。现在,假设我们在dll中查找的函数类型为:

int add(int a, int b);
但是如果我们把它换成另一种类型

typedef int (*sum)(int a, int b, int c);
会发生什么?C运行时会对此抱怨吗


谢谢

长话短说,这是未定义的行为。在C中调用参数数目错误的函数(即使没有
dlopen
/
dlfree
,也可以通过强制转换函数指针来实现)会产生未定义的行为

对于被调用者干净调用约定,如
stdcall
,使用错误数量或类型的参数将产生堆栈不平衡(被调用者将堆栈调整到错误位置)。堆栈不平衡会破坏调用方的返回地址和局部变量,从而很快杀死程序(如果幸运的话)


对于调用方清理调用约定,其效果非常类似于使用错误数量的参数调用(例如,
printf
):使用垃圾参数可能会导致函数行为异常,但您的程序可能不会崩溃。(这通常是不可取的;例如,攻击者可以利用它来控制您的程序)。

不,C运行时不会抱怨。但是调用函数指针可能不起作用(也就是说,结果是未定义的)。@jxh那么在这种情况下基本上会发生灾难吗?@Guoqin这正是“UB”的意思。任何事情都有可能发生——从“它工作完美”到“我的电脑冒烟”。实际上,在Linux下使用64位SYSV ABI的x86-64上,不可能发生任何事情;在这里,一个额外的整数参数将放在寄存器
rdx
中,函数将忽略该参数。不过,我不会对其他的ABI那么肯定。@郭琴:取决于ABI。例如,在x86
stdcall
中,所有参数都被推送到堆栈上,被调用方恢复堆栈。如果函数是
stdcall
,则使用错误数量的参数调用它将使堆栈失衡。这是一个非常坏的消息。但是对于其他ABI,比如@IwillnotexistIdonotexist提到的64位ABI,或者ARM ABI,一定数量的参数首先放在寄存器中,多余的参数放在堆栈中。