【问题标题】:Exe crashes after coming out of the method in c++从c ++中的方法出来后Exe崩溃
【发布时间】:2016-07-04 06:24:39
【问题描述】:

我有一个方法 FormatOutPut() 在 C++ 中内部调用“回调”方法 MyFunct()。当控件出现FormatOutPut() 时发生崩溃。回调方法MyFunct() 只是在屏幕上打印输出。当我使用 windbg 调试代码时,我得到了以下跟踪,

(1250.1270): Stack buffer overflow - code c0000409 (!!! second chance !!!)

我的猜测是,FormatOutPut() 在堆栈上的返回地址被回调方法破坏了。因此,当控制权转移回调用方法时,它会崩溃。

当我注释掉回调方法时,一切正常。对此的任何意见都会有很大帮助。

回调方法原型如下,

typedef void(__stdcall *MyCallBack)(char*,char*,char*,char*,char*,char*,char*,char*,char*,char*,int, int );

正文:-

void MyCallbackRoutine(char* GetFeature,char* GetVersion,char* GetStartDate, char* GetExpireDate, char* GetUsers,char* GetKey,char* GetVendorString, char* GetHostID,char* GetErrorMsg,char* GetLicense,int GetCheckOutStatus, int nCount)     
{
        if ( nCount == 0 )    
        {  

            _strtime_s( timeCallbackstart, 10 );

            time(&startCallbackstart);   

            bOnlyOnce = true;    
        }    
    cout << endl;    
    cout << "-------------------------------------------------------" << endl;    
    cout << "GetCheckOutStatus: " << GetCheckOutStatus << endl;     
    cout << "GetErrorMsg:       " << GetErrorMsg << endl;     
    cout << endl;    
    cout << "GetFeature:        " << GetFeature << endl;    
    cout << "GetVersion:        " << GetVersion << endl;     
    cout << "GetStartDate:      " << GetStartDate  << endl;     
    cout << "GetExpireDate:     " << GetExpireDate << endl;     
    cout << "GetUsers:          " << GetUsers << endl;     
    cout << "GetKey:            " << GetKey << endl;     
    cout << "GetVendorString:   " << GetVendorString << endl;     
    cout << "GetHostID:         " << GetHostID << endl;     
    cout << "GetLicense:        " << GetLicense << endl;     
    cout << endl;    
    cout << "Licenscounter:     " << nCount << endl;     
    cout << "------------------------------------------------------" << endl;    
    cout << endl;

}    

感谢和问候, AKJ

【问题讨论】:

  • 我不想成为必须调用这样一个函数的程序员。十二个参数,其中 10 个是字符指针。哎呀。
  • 即使我讨厌 :P.. 在 win7 操作系统上使用 VS2008 编译器编译时,此代码运行良好。我在使用 VS2013 和 win10 操作系统时遇到问题。
  • 所以你发布了一个回调原型。除了它有很多参数之外,我们要从中提取什么信息?发布这个回调调用的内容怎么样?与其注释掉调用,不如注释掉回调函数本身的主体,只写一个return 语句。如果错误消失,那么您在该功能中所做的事情有问题。如果错误仍然存​​在,那么它与(很可能)调用约定不匹配或参数不匹配有关。
  • void MyCallbackRoutine(char* GetFeature, char* GetVersion,char* GetStartDate, char* GetEndDate, char* GetUsers, char* GetK, char* GetVString, char* GetHostID, char* GetErrorMsg, char* GetAllString ,int GetStatus, int nCount) { if ( nCount == 0 ) {_strtime_s( timeCallbackstart, 10 );时间(&startCallbackstart); bOnlyOnce = true;} cout
  • @AKJ 您在回调原型上指定了__stdcall 调用约定,但是您在 cmets 中发布的函数(请放在原帖中)并未显示使用此调用约定.默认情况下,C++ 程序使用__cdecl 调用约定,而不是__stdcall。调用约定不匹配可能导致崩溃(通常基于堆栈,但通常不是溢出问题)。

标签: c++ c methods callback


【解决方案1】:

我看到的问题是您对函数原型的typedef__stdcall 调用约定与回调函数本身不匹配。如果调用约定不匹配,从被调用函数返回时可能会出现堆栈问题。

更多关于calling conventions here

函数的typedef如下:

typedef void(__stdcall *MyCallBack)(char*,char*,char*,char*,char*,char*,char*,
                                    char*,char*,char*,int, int );

但是分配为回调的函数有这个:

void MyCallbackRoutine(char* GetFeature,char* GetVersion,char* GetStartDate, 
                       char* GetExpireDate, char* GetUsers,char* GetKey,
                       char* GetVendorString, char* GetHostID,
                       char* GetErrorMsg,char* GetLicense,
                       int GetCheckOutStatus, int nCount)     

参数个数和类型匹配,返回类型void匹配,但是不匹配的关键元素是缺少__stdcall。默认情况下,调用约定为__cdecl(如果未指定)。更正应该是:

void __stdcall MyCallbackRoutine(char* GetFeature,char* GetVersion,char* GetStartDate, 
                       char* GetExpireDate, char* GetUsers,char* GetKey,
                       char* GetVendorString, char* GetHostID,
                       char* GetErrorMsg,char* GetLicense,
                       int GetCheckOutStatus, int nCount)     

请注意,当分配一个定义与原型不匹配的函数时,编译器应该已经发现了这个问题,正如this small example 演示的那样(如果发生此编译器错误,请不要尝试通过应用C 来修复它-样式强制转换以关闭编译器——这不是修复)。

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 1970-01-01
    相关资源
    最近更新 更多