2016-07-04 21 views
-2

Ich habe eine Methode FormatOutPut(), die intern ruft eine "CallBack" -Methode MyFunct() in C++. Es gibt einen Absturz, wenn die Kontrolle FormatOutPut() herauskommt. Die Callback-Methode MyFunct() druckt nur die Ausgabe auf dem Bildschirm. Wenn ich den Code mit windbg ausgetestet bekam ich folgende Spuren,Exe stürzt nach dem Verlassen der Methode in C++

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

Was ich vermute ich, dass die Absenderadresse auf dem Stack für die FormatOutPut(), durch die Callback-Methode beschädigt ist. Wenn die Steuerung zurück zur Aufrufmethode verschoben wird, stürzt sie ab.

Wenn ich die Callback-Methode auskommentieren, funktioniert alles gut. Irgendwelche Eingaben dazu werden große Hilfe sein.

Callback-Methode Prototyp ist als unten,

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

Körper: -

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; 

}  

Danke und Grüße, AKJ

+3

Ich würde es hassen, der Programmierer zu sein, der eine solche Funktion aufrufen muss. Zwölf Parameter, wobei 10 Zeichenzeiger sind. Huch. – PaulMcKenzie

+0

Auch ich hasse: P .. Dieser Code funktionierte gut, wenn mit VS2008 Compiler auf Win7 OS kompiliert. Ich habe Probleme, wenn ich VS2013 und win10 OS verwende. – AKJ

+2

Sie haben also einen Callback-Prototyp veröffentlicht. Welche Informationen sollen wir daraus gewinnen, außer dass es eine Menge Parameter gibt? Wie wäre es mit dem Posten, was dieser Callback anruft? Anstatt den Aufruf zu kommentieren, müssen Sie den Text der Callback-Funktion selbst auskommentieren und nur eine 'return'-Anweisung haben. Wenn der Fehler verschwindet, ist es etwas, das Sie in dieser Funktion tun, die fehlerhaft ist. Wenn der Fehler weiterhin besteht, hat dies etwas mit (mehr als wahrscheinlich) einer Nichtübereinstimmung der Aufrufkonvention oder einer Nichtübereinstimmung der Parameter zu tun. – PaulMcKenzie

Antwort

1

Das Problem, das ich sehe, ist, dass Ihre Aufrufkonvention von __stdcall für die typedef der Funktion Prototyp und die Callback-Funktion selbst nicht übereinstimmt. Wenn die Aufrufkonvention nicht übereinstimmt, können Stapelprobleme auftreten, wenn von der aufgerufenen Funktion zurückgegeben wird.

Mehr unter calling conventions here.

Die typedef für die Funktion ist wie folgt:

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

aber die Funktion, die als Rückruf zugewiesen wird, hat dies:

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)  

Die Anzahl und Art von Parametern übereinstimmen, die Rückkehr Geben Sie void entspricht, aber das Schlüsselelement, das nicht übereinstimmt, ist, dass __stdcall fehlt. Standardmäßig ist die Aufrufkonvention __cdecl, falls nicht angegeben. Die Korrektur sollte sein:

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)  

Beachten Sie, dass der Compiler das Problem haben sollte, wenn die Zuordnung einer Funktion, die Definition ist abgeholt nicht den Prototyp übereinstimmen als this small example demonstriert (Wenn dieser Compiler-Fehler auftritt, versuchen Sie nicht, es zu beheben durch Anwenden einer C-Cast, um den Compiler zu schließen - das ist kein Fix).