MSVS 2010 C++;编译器和堆栈对齐问题? 我的问题是MSVS 2010 C++编译器在从运行时函数调用(GeCopyTald+GETMeimeAd句柄)返回的另一个DLL中,以某种方式生成代码,然后尝试以这样的方式对齐堆栈: CALL DWORD PTR DS:[2000367C] ; apiresolvedinruntime.dll ADD ESP,12 ; <- this is the stack alignment 呼叫DWORD PTR DS:[2000367C];apiresolvedinruntime.dll 增加ESP,12

MSVS 2010 C++;编译器和堆栈对齐问题? 我的问题是MSVS 2010 C++编译器在从运行时函数调用(GeCopyTald+GETMeimeAd句柄)返回的另一个DLL中,以某种方式生成代码,然后尝试以这样的方式对齐堆栈: CALL DWORD PTR DS:[2000367C] ; apiresolvedinruntime.dll ADD ESP,12 ; <- this is the stack alignment 呼叫DWORD PTR DS:[2000367C];apiresolvedinruntime.dll 增加ESP,12,c++,visual-studio,assembly,calling-convention,C++,Visual Studio,Assembly,Calling Convention,您没有使用正确的调用约定调用运行时加载的函数。调用约定指定对堆栈发生的情况的默认处理。最有可能的是,DLL是使用调用约定(例如Windows DLL使用的)编译的,该约定指定被调用函数应该清理堆栈,但调用代码是使用调用约定(默认)的函数指针声明的。在\uu cdecl下,函数支持可变参数,因此调用方需要清理堆栈,因为被调用函数不知道传递了多少参数 您需要验证DLL和调用代码是否使用相同的调用约定编译。您没有使用正确的调用约定调用运行时加载的函数。调用约定指定对堆栈发生的情况的默认处理。最有可能的

您没有使用正确的调用约定调用运行时加载的函数。调用约定指定对堆栈发生的情况的默认处理。最有可能的是,DLL是使用调用约定(例如Windows DLL使用的)编译的,该约定指定被调用函数应该清理堆栈,但调用代码是使用调用约定(默认)的函数指针声明的。在
\uu cdecl
下,函数支持可变参数,因此调用方需要清理堆栈,因为被调用函数不知道传递了多少参数


您需要验证DLL和调用代码是否使用相同的调用约定编译。

您没有使用正确的调用约定调用运行时加载的函数。调用约定指定对堆栈发生的情况的默认处理。最有可能的是,DLL是使用调用约定(例如Windows DLL使用的)编译的,该约定指定被调用函数应该清理堆栈,但调用代码是使用调用约定(默认)的函数指针声明的。在
\uu cdecl
下,函数支持可变参数,因此调用方需要清理堆栈,因为被调用函数不知道传递了多少参数


您需要验证DLL和调用代码是否使用相同的调用约定编译。

请发布(a)模块中函数的声明,(b)如何通过
GetProcAddress获取函数指针,以及(c)如何调用函数。听起来像是调用约定不匹配:\u stdcall vs.\u cdecl,也许。您是否正确地将函数指针的类型标注为与您正在调用的函数匹配的类型?请发布(a)模块中函数的声明,(b)如何通过
GetProcAddress
获取函数指针,以及(c)如何调用函数。听起来像是调用约定不匹配:\u stdcall vs.\u cdecl,也许。您是否正确地用与您正在调用的函数匹配的函数指针来注释函数指针的类型?FWIW,这个问题在x64上被掩盖,因为这两个调用约定在Windows x64 ABI中是相同的。@Reuben:这是因为在amd64上有一个标准的调用约定(相当于x86上的
\uu fastcall
). x86从未有过标准的调用约定。(
\uu fastcall
在x64处理器上更有用,因为有更多的寄存器可用)是的,我知道:)我只是把这些信息留在这里作为问题的背景资料。FWIW,虽然它是基于x86上的_fastcall的精神,但据我所知,它并不完全等同;堆栈对齐、可装入寄存器的arg数、寄存器中arg所需的溢出空间等似乎都有所不同。没错,使用第三方软件是一个地狱,不同的调用约定是问题所在,thanks@reuben:是的,它不完全一样,但它的工作原理是一样的。(也就是说,许多参数通过寄存器而不是堆栈传递)这些差异是由于长模式下的对齐要求以及长模式下更多寄存器可用的事实造成的。FWIW,这个问题在x64上被掩盖,因为这两个调用约定在Windows x64 ABI中是相同的。@鲁本:这是因为在amd64上有一个标准调用约定(相当于x86上的
\uu fastcall
)。x86从未有过标准的调用约定。(
\uu fastcall
在x64处理器上更有用,因为有更多的寄存器可用)是的,我知道:)我只是把这些信息留在这里作为问题的背景资料。FWIW,虽然它是基于x86上的_fastcall的精神,但据我所知,它并不完全等同;堆栈对齐、可装入寄存器的arg数、寄存器中arg所需的溢出空间等似乎都有所不同。没错,使用第三方软件是一个地狱,不同的调用约定是问题所在,thanks@reuben:是的,它不完全一样,但它的工作原理是一样的。(也就是说,许多参数是通过寄存器而不是通过堆栈传递的)这些差异是由于长模式下的对齐要求以及长模式下有更多寄存器可用这一事实造成的。