Memory management 什么是堆栈不平衡?

Memory management 什么是堆栈不平衡?,memory-management,f#,stack,terminology,Memory Management,F#,Stack,Terminology,读了这篇文章后,我在一段中偶然发现了术语堆栈不平衡,这是一个警告,也许是一个预兆 我继续搜索,但只能找到与堆栈不平衡作斗争的人,没有任何一般性的解释 奖金问题: 它只影响f?或者是C、C++、Python、java等? p、 如有必要,请更改问题的标签我们前几天刚刚看到了这一点(使用c#和c++进行编组) 我建议您参考一页中的文本: PinVokeStack托管调试助手(MDA)是 当CLR检测到平台后的堆栈深度 给定调用,invoke调用与预期堆栈深度不匹配 DllImportAttribut

读了这篇文章后,我在
一段中偶然发现了术语
堆栈不平衡
,这是一个警告,也许是一个预兆

我继续搜索,但只能找到与堆栈不平衡作斗争的人,没有任何一般性的解释

奖金问题: 它只影响f?或者是C、C++、Python、java等?
p、 如有必要,请更改问题的标签

我们前几天刚刚看到了这一点(使用c#和c++进行编组)

我建议您参考一页中的文本:

PinVokeStack托管调试助手(MDA)是 当CLR检测到平台后的堆栈深度 给定调用,invoke调用与预期堆栈深度不匹配 DllImportAttribute属性中指定的约定以及 托管签名中参数的声明

我意识到这是针对一个特定的编译器警告,但是页面给出了一些关于堆栈不平衡是什么、是什么原因、症状是什么以及如何解决它的信息。正如Daniel所说,这通常是由于托管和非托管的签名不匹配


希望这能有所帮助。

当用于跟踪被调用函数、参数和返回值的数据结构损坏或未对齐时,会出现堆栈不平衡

大多数情况下,堆栈是一个内存指针,用于存储当前函数调用返回调用方时控制将在其中恢复的地址。这方面有不同的变体,有时函数的参数以及返回值也会附加到堆栈中。这里最重要的是,调用者和被调用者应该就如何在被调用者退出时将其恢复到先前的状态达成一致。此协议通常称为呼叫约定

在.NET中,堆栈不平衡是纯托管代码中罕见的甚至不存在的问题。但是,在调用非托管代码时,这可能是一个常见的问题,因为您需要告诉编译器应该如何调用该方法,这意味着应该如何按照调用约定清理堆栈

在windows上,有一些标准调用约定涵盖了大部分调用情况

stdcall-被调用方将在退出时修复堆栈。
fastcall-除了返回地址之外,可能不需要修复堆栈,而是使用CPU寄存器传递参数。
cdecl-调用方将在被调用函数返回后修复堆栈

此处提供正式参考:

这也是令人感兴趣的:


在给定的开发领域中,这往往不是问题。每种语言通常都有一个对所有方法调用都是隐式的约定。C/C++使用相同的约定来调用C/C++调用,Python用于其他Python调用,等等。当跨域时,如果一个域与另一个域不使用相同的调用,这可能会成为一个问题。可能在windows中最常见的是,使用“C”样式声明(cdecl)导出的函数在调用时可能会导致堆栈不平衡(或更糟),就好像它具有stdcall约定一样,这是WINAPI(windows系统)调用可以识别的方法。

简言之,这意味着您正在使用错误的签名调用非托管函数。它会影响任何带有to非托管代码的语言。+1表示非常通用且与语言无关的描述,并带有特定示例。