【问题标题】:ESP Not saved across function call / Runtime Error #0ESP 未在函数调用/运行时错误 #0 中保存
【发布时间】:2011-10-06 18:40:48
【问题描述】:

我收到一个奇怪的错误,抱怨我假设的堆栈损坏,我已经对其进行了一些调试,但我还没有发现问题所在。我似乎也无法在 Visual Studio 2010 中实现 nothrow!

XYZ::XYZ(char * d)
{
    hostname = new char[HOSTNAME_LENGTH];
    ip = new char[IP_ADDR_LENGTH];

    /*Dynamic Memory*/
    memset(hostname, 0, HOSTNAME_LENGTH);
    memset(ip, 0, IP_ADDR_LENGTH);

    //strncpy(hostname, d, HOSTNAME_LENGTH);

    if(dWSAStartup(MAKEWORD(2,2), &wsd) == 0) //Crashes Here!
    //And so on..

dWSAStartup 从 ws2_32.dll 动态链接并具有正确的函数参数类型转换:

typedef int (*WSAS)(WORD, LPWSADATA); //WSAStartup

不,FreeLibrary 函数还没有被调用——所以函数指针是有效的!

这个错误是唯一阻止我的东西!有没有人给我指点?

【问题讨论】:

  • std::string过敏? wsd 是什么?这些动态char 缓冲区与您的问题有什么关系? WSAS 是从哪里来的?我会拿出我的 ESP。
  • 可悲的是,我是。我把它包括在内是因为我知道如果我不展示它就会有人抱怨。这是一个动态链接的函数,所以 WSAS 是指向内存内部函数的指针。
  • 您可以尝试重新构建您的应用程序,这种巫术有时会有所帮助。
  • @Saustin:为什么?为什么你忽略了我的其他问题?
  • 它被称为重叠响应 :) 不同的程序员有不同的习惯——问题不是我不使用 std::string,而是我遇到了运行时错误。我已经重建了应用程序,没有骰子。

标签: c++ winapi


【解决方案1】:

typedef int (*WSAS)(WORD, LPWSADATA); //WSA启动

错了,缺少调用约定。它默认为 __cdecl,这不是在 winsock2.h 中声明的方式。这就是为什么您要获得运行时诊断,在调用之后它将参数从堆栈中弹出,这已经由 WSAStartup() 完成。结果是堆栈不平衡。修复:

typedef int (__stdcall * WSAS)(WORD, LPWSADATA); //WSAStartup

实际使用的声明器是 FAR PASCAL,网络 apis 强烈保留了上个世纪。给你的编译器一点爱,因为它会警告你,如果没有自动生成的调试代码,不平衡的堆栈是非常难以诊断的。

【讨论】:

  • 哇!完美的!我不认为修复会那么那么容易!我应该看看 winsocks 标头中的声明,谢谢。
猜你喜欢
  • 2023-03-06
  • 2012-01-30
  • 2012-04-22
  • 1970-01-01
  • 2011-01-26
  • 2013-07-03
  • 1970-01-01
  • 2018-11-28
相关资源
最近更新 更多