从c ++中的方法出来后,exe崩溃了

时间:2016-07-04 06:24:39

标签: c++ c methods callback

我有一个方法FormatOutPut(),它在C ++内部调用“callBack”方法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

1 个答案:

答案 0 :(得分:1)

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

更多关于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样式转换来关闭编译器 - 这不是一个修复程序。