none
Stack overflow durch DLL / Deklarationsprobleme bei Erstellung einer DLL RRS feed

  • Frage

  •  

     

    Hallo Zusammen,

    Situation:
    ich habe eine Fremdapplikation (ziemlich sicher VB basierend), die über eine offenen Schnittstelle die Einbindung eigener Hardware ermöglicht. Die von mir in Visual C++ erstellte DLL funktioniert auch wunderbar und sämtliche Aufrufe werden reibungslos abgearbeitet.

    Problem:
    Nach kurzer Zeit meldet die aufrufende Applikation einen Fehler 28 (Stack overflow?)

    Eingrenzung:
    Um Probleme mit rekursiven Aufrufen auszuschließen, habe ich alle Aufrufe auf das Minimum reduziert (Wo möglich nur noch "return true"). Ausserdem kann ich ausschließen, dass ein Aufruf einer Funktion in der DLL erfolgt, obwohl der letzte Aufruf noch nicht abgearbeitet ist. Zum Zeitpunkt des Overflows ist die Initialisierung des Treibers erledigt und MLDraw und MLParams werden abwechselnd mehrmals pro Sekunde aufgerufen (bis eben der Stack überläuft).
    Da eigentlich "kein" Code mehr in der DLL steckt, vermute ich den Fehler in der Deklaration.

    In der Hoffnung, dass hier irgendjemand jetzt lacht und schreibt: "Da hast Du lediglich einen wichtigen Parameter vergessen!"
    Gruß
    Joe

    Header:

     

    // ML_Driver.h
    
    extern "C"
    {
    	__declspec(dllexport) unsigned short MLRegisterDriver(char *b);
    	__declspec(dllexport) bool MLDevicePresent(void);
    	...
    	__declspec(dllexport) unsigned short MLOutputChannels(void);
    }

     

    ML_Driver.cpp:

    // ML_Driver
    
    #include "ML_Driver.h"
    #define STRICT
    #include <stdexcept>
    #include <windows.h>
    
    
    BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
    	return true;
    }
    
    unsigned short MLRegisterDriver(char *b)
    // function MLRegisterDriver(b: PChar): word stdcall;
    // Kopiert den Namen "MLDevice" in den Buffer
    {
    	char tempstr[] = "MLDevice";
    	for(int i=0; i<sizeof(tempstr); i++)
    		b[i] = tempstr[i];
    	return 0;
    }
    
    bool MLDevicePresent(void)
    // function MLDevicePresent: boolean; stdcall;
    {
    	return true;
    }
    
    // ...
    
    unsigned short MLOutputChannels(void)
    //function MLOutputChannels: word stdcall;
    {
    	return true;
    }


    • Bearbeitet Murmeljoe Dienstag, 22. Februar 2011 16:56
    Montag, 21. Februar 2011 15:18

Antworten

  • Nochmals vielen Dank für die super schnelle und kompetente Hilfe, die jetzt auch zur Lösung geführt hat:

    VB kümmert sich nicht um das Stackhandling, sondern erwartet dies von der aufgerufenen DLL. Der Hinweis von Martin Richter führte dabei direkt zum Erfolg. Weil _stdcall aber den exportierten Funktionsnamen ändert, muss zusätzlich noch von _declspec(dllexport) auf DEF-File umgestellt werden.

    Mit Dank und Gruß
    Joe

    Header:

    // ML_Driver.h
    	unsigned short _stdcall MLRegisterDriver(char *b);
    	bool _stdcall MLDevicePresent(void);
    	...
    	unsigned short _stdcall MLOutputChannels(void);
    

     

    DEF-File:

    LIBRARY ML_Driver
    EXPORTS
    	MLRegisterDriver
    	MLDevicePresent
    	...
    	MLOutputChannels
    

    • Als Antwort markiert Murmeljoe Dienstag, 22. Februar 2011 16:46
    Dienstag, 22. Februar 2011 16:46

Alle Antworten

  • Da wird man Dir nicht helfen können, wenn man keine Kenntnisse um den Client hat, der Deine DLL benutzt. Dein Code hat keine Probleme, soweit ich das sehen kann und sofern, Deine Daten-Kopiererei korrekt ist.

    Mich macht stutzig, dass in den Comments etwas vom stdcall steht Du aber keine Calling-Convention definierst.
    Kontroliere wirklich welche Calling Convention benötigt wird und seze diese explicit für die entsprechenden Funktionen.

    Ansonten wende Dich an den Hersteller!


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Dienstag, 22. Februar 2011 11:18
  • Vielen Dank für die schnelle Antwort. In der Doku zur Applikation ist ein Beispiel einer in Delphi geschriebenen DLL dabei. Die Delphi-Funktionsaufrufe habe ich als Gedächtnisstütze in die Comments kopiert - deshalb der "komische" Syntax.  ;-)

    Nachdem meine Deklaration im Header anscheinend nicht völliger Blödsinn ist, werde ich mich hinter die Calling Convention klemmen. Hier könnte ich etwas bei der "Übersetzen" von Delphi nach C++ verbogen haben. Kenne mich diesbezüglich aber noch nicht genug aus und werde mich also zuerst noch etwas belesen.

    Gruß
    Joe

    Dienstag, 22. Februar 2011 12:30
  • FYI: Die Calling Convention ist wichtig, hier wird festgelegt in welcher Folge die Argumente auf dem Stack landen und wer sie abräumt.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Dienstag, 22. Februar 2011 14:26
  • Nochmals vielen Dank für die super schnelle und kompetente Hilfe, die jetzt auch zur Lösung geführt hat:

    VB kümmert sich nicht um das Stackhandling, sondern erwartet dies von der aufgerufenen DLL. Der Hinweis von Martin Richter führte dabei direkt zum Erfolg. Weil _stdcall aber den exportierten Funktionsnamen ändert, muss zusätzlich noch von _declspec(dllexport) auf DEF-File umgestellt werden.

    Mit Dank und Gruß
    Joe

    Header:

    // ML_Driver.h
    	unsigned short _stdcall MLRegisterDriver(char *b);
    	bool _stdcall MLDevicePresent(void);
    	...
    	unsigned short _stdcall MLOutputChannels(void);
    

     

    DEF-File:

    LIBRARY ML_Driver
    EXPORTS
    	MLRegisterDriver
    	MLDevicePresent
    	...
    	MLOutputChannels
    

    • Als Antwort markiert Murmeljoe Dienstag, 22. Februar 2011 16:46
    Dienstag, 22. Februar 2011 16:46