我有一个方法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
答案 0 :(得分:1)
我看到的问题是,__stdcall
对函数原型typedef
的调用约定与回调函数本身不匹配。如果调用约定不匹配,则从被调用函数返回时可能会出现堆栈问题。
该功能的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
样式转换来关闭编译器 - 这不是一个修复程序。