我们最近试图将我们的一些Visual Studio项目拆分成库,并且一切似乎都在一个testing项目中编译和构build,其中一个库项目作为依赖项。 但是,试图运行该应用程序给了我们下面的令人讨厌的运行时错误消息: 运行时检查失败#0 – ESP的值在函数调用中未正确保存。 这通常是调用用不同调用约定声明的函数指针的结果。 我们甚至从来没有为我们的函数指定调用约定(__cdecl等),使所有编译器开关保持默认状态。 我检查了一下,项目设置对于在库和testing项目中调用约定是一致的。 更新:我们的一个开发人员将“基本运行时间检查”项目设置从“Both(/ RTC1,equiv。to / RTCsu)”更改为“Default”,运行时间消失,程序运行显然正常。 我完全不信任这个。 这是一个合适的解决scheme,还是一个危险的黑客?
这几天我碰到了很多__stdcall 。 而在我看来,MSDN并没有很清楚地解释它的真正含义, 何时以及为什么要使用它,如果是的话。 如果有人提供解释,我将不胜感激,最好有一两个例子。 谢谢
我目前正在开发Windows的C ++库,将作为DLL分发。 我的目标是最大化二进制互操作性; 更确切地说,我的DLL中的函数必须可以从多个版本的MSVC ++和MinGW编译的代码中使用,而无需重新编译DLL。 但是,我很困惑哪个调用约定是最好的, cdecl或stdcall 。 有时我会听到像“C调用约定是唯一一个保证与编译器相同的调用约定”这样的语句,这与“ 对cdecl的解释有一些变化,特别是在如何返回值 ”等语句形成对比。 这似乎并不阻止某些库开发人员(如libsndfile )在分发的DLL中使用C调用约定,而没有任何可见的问题。 另一方面, stdcall调用约定似乎是明确的。 据我所知,所有的Windows编译器基本上都需要遵循它,因为它是用于Win32和COM的惯例。 这是基于这样一个假设:没有Win32 / COM支持的Windows编译器不会非常有用。 在论坛上张贴了很多代码片段声明函数为stdcall但我似乎无法find明确解释为什么一个单一的职位。 这里有太多相互矛盾的信息,每次search都会给我不同的答案,这并不能帮助我在两者之间做出决定。 我正在寻找一个清晰的,详细的,辩论的解释,为什么我应该select一个在另一个(或为什么两个是相等的)。 请注意,这个问题不仅适用于“经典”function,而且适用于虚拟成员函数调用,因为大多数客户端代码将通过“接口”,纯虚拟类(以下描述的模式在这里和那里 )与我的DLL接口。
我试图深入了解编程语言的低级操作是如何工作的,特别是他们如何与OS / CPU进行交互。 我可能在堆栈溢出的每个堆栈/堆相关的线程中都读过每个答案,它们都很精彩。 但是还有一件事我还没完全理解。 在伪代码中考虑这个function,这往往是有效的锈代码;-) fn foo() { let a = 1; let b = 2; let c = 3; let d = 4; // line X doSomething(a, b); doAnotherThing(c, d); } 这就是我认为堆栈看起来像X行: Stack a +————-+ | 1 | b +————-+ | 2 | c +————-+ | 3 | d +————-+ | 4 | […]
我正在学习Win32编程, WinMain原型如下所示: int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show ) 我很困惑这个WINAPI标识符是什么,并发现: #define WINAPI __stdcall 这是做什么的? 我很困惑,因为在返回types之后有什么东西。 什么是__stdcall ? 返回types和函数名称之间有什么意义时,这意味着什么?
可能重复: 我怎样才能find调用当前方法的方法? 我有一个对象的方法在对象内的多个地方被调用。 有没有一个简单快捷的方法来获得这个方法的名字,这个方法叫做这个stream行的方法。 伪代码示例: public Main() { PopularMethod(); } public ButtonClick(object sender, EventArgs e) { PopularMethod(); } public Button2Click(object sender, EventArgs e) { PopularMethod(); } public void PopularMethod() { //Get calling method name } 在PopularMethod()我想看到Main的价值,如果它从Main调用…我想看到“ ButtonClick ”,如果从ButtonClick调用ButtonClick PopularMethod() 我在看System.Reflection.MethodBase.GetCurrentMethod()但不会让我的调用方法。 我已经看了StackTrace类,但是我真的不喜欢每次调用这个方法时运行整个堆栈跟踪。
AMD有一个ABI规范,描述了在x86-64上使用的调用约定。 除了拥有自己的x86-64调用约定的Windows,所有的操作系统都遵循它。 为什么? 有没有人知道这种差异的技术,历史或政治原因,还是纯粹是NIH综合征的问题? 我知道不同的操作系统可能对更高级别的东西有不同的需求,但是这并不能解释为什么例如Windows上的寄存器parameter passing顺序是rcx – rdx – r8 – r9 – rest on stack人都使用rdi – rsi – rdx – rcx – r8 – r9 – rest on stack 。 PS我知道这些调用约定是如何不同的,我知道在哪里可以find细节。 我想知道的是为什么 。 编辑:如何,见例如维基百科条目和从那里的链接。