Fehler beim Beenden der Anwendung, nur bei aktiver XP-Theme



  • Ich finde es direkt bei DllEntryPoint() am besten. Das ist allerdings Geschmackssache.

    Da hab ich die Ergänzung auch hingepackt. Dann lag ich nicht so falsch.
    Da die meisten meiner DLLs Formulare und damit auch Komponenten enthalten werde ich die einfach in alle DLLs einfügen.

    Über Packages hab ich auch schon etwas gelesen. Auch das es mit denen wohl weniger solche Probs geben soll. Jedoch hab ich mich da nicht weiter vertieft.
    Können Packages denn auch so wie DLLs statisch geladen werden und dann mit einer Header-Datei die in den Packages untergebrachten Funktionen bekannt gemacht werden? Nur so nebenbei. Obwohl ich jetzt keine besondere Lust verspüre alles in Packages umzuändern. 🙂



  • Netzschleicher schrieb:

    Können Packages denn auch so wie DLLs statisch geladen werden und dann mit einer Header-Datei die in den Packages untergebrachten Funktionen bekannt gemacht werden? Nur so nebenbei.

    Ja. Um statisch gegen ein Laufzeit-Package zu linken, mußt du die zugehörige .bpi-Datei (nicht die .lib-Datei!) referenzieren; das entspricht also der .lib-Datei einer DLL. (Genaueres hier: http://docwiki.embarcadero.com/RADStudio/de/Packages_und_Standard-DLLs). Die Handhabung ist ansonsten wie die von DLLs, nur daß du mit Packages ein bißchen flexibler bist. Ein Package-Projekt ist sozusagen ein DLL-Projekt und eine statische Bibliothek zugleich: du kannst es als DLL benutzen und statisch oder dynamisch binden, oder du kannst es statisch in deine Executable hineinkompilieren.

    Netzschleicher schrieb:

    Obwohl ich jetzt keine besondere Lust verspüre alles in Packages umzuändern. 🙂

    Brauchst du ja nicht; es funktioniert auch so 😉



  • Ich hab das mit dem Package gleich mal in einem Testprojekt versucht. Hat einwandfrei geklappt. Ich musste lediglich nicht die von Dir genannte BPI sondern die erzeugte LIB-Datei dazulinken, dann hat das ganze auch mit einem Package funktioniert. Und das Fehlerfrei ohne die kleine Ergänzung die Du mir letzte Nacht genannt hast. 🙂 🙂 🙂

    Wäre das eingentliche Thema meines Treads hier nicht etwas für die FAQ. Ich denke es gibt bestimmt noch mehr Leute wie ich die vielleicht dieses Problem haben.



  • Netzschleicher schrieb:

    Ich hab das mit dem Package gleich mal in einem Testprojekt versucht. Hat einwandfrei geklappt. Ich musste lediglich nicht die von Dir genannte BPI sondern die erzeugte LIB-Datei dazulinken, dann hat das ganze auch mit einem Package funktioniert.

    Langsam. Die BPI ist die Import-Bibliothek und entspricht der LIB-Datei deiner DLL. Die LIB-Datei eines Packages hingegen entspricht einer statischen Bibliothek - das Laufzeit-Package ist also gar nicht mehr involviert, denn so linkst du den Package-Inhalt in dein Projekt hinein. Das kann auch sinnvoll sein, aber wenn du mehrere Module à la DLLs willst, mußt du die BPI-Datei nehmen.



  • Sorry, hatte gestern noch meinen Fernseher angeschlafen.... 🙄

    Ah, ok. Hab das jetzt nochmal nachvollzogen. Stimmt, wenn ich die LIB-Datei einbinde funktioniert es auch ohne das die BPL vorhanden ist.
    Dann muß ich mal stöbern wie ich die BPI-Datei in ein Projekt einbinde. Wenn ich das per #pragma link mache, oder die Datei dem Projekt in der Projektverwaltung hinzufüge, kommt beim Linken immer die Meldung das ein nicht auflösbaren externes Symbol referenziert wurde.

    Werd das ganze mal als Testprojekt auf der Platte behalten.

    Die andere DLL Geschichte funzt jetzt absolut prima.



  • Netzschleicher schrieb:

    Dann muß ich mal stöbern wie ich die BPI-Datei in ein Projekt einbinde. Wenn ich das per #pragma link mache, oder die Datei dem Projekt in der Projektverwaltung hinzufüge, kommt beim Linken immer die Meldung das ein nicht auflösbaren externes Symbol referenziert wurde.

    Hast du die Funktion denn korrekt mit __declspec(dllexport) definiert? Bei mir gehts dann problemlos.



  • Sch..., ertappt. Hatte vergessen die Header-Datei für den Im- Export zu includieren.

    #ifndef _TESTINC
    #define _TESTINC
    
    #ifdef __DLL__
    	#define __EXPORT_TYPE __declspec(dllexport)
    #else
    	#define __EXPORT_TYPE __declspec(dllimport)
    #endif
    //-----------------------------------------------------------------------------
    __EXPORT_TYPE void showBPLform(void);
    //-----------------------------------------------------------------------------
    
    #endif
    

    Allerdings konnte ich die BPL-Datei dann nicht linken. Es kamen 74 Linkerfehler mit nicht auflösbaren externen Symbolen. Alle haben mit der VCL zu tun. Ohne die Header-Datei kompiliert und linkt die BPL, allerdings exportiert diese dann meine Beispielfunktion ja nicht. 😕 😕 😕



  • Netzschleicher schrieb:

    Allerdings konnte ich die BPL-Datei dann nicht linken. Es kamen 74 Linkerfehler mit nicht auflösbaren externen Symbolen.

    Ah, richtig - wenn dein Package die VCL benutzt, mußt du "vcl.bpi" zu den erforderlichen Packages hinzufügen. Desgleichen für weitere Komponenten, die du referenzierst - etwa für die Ribbon-Controls bräuchtest du noch "vclribbons.bpi".

    Einfach Rechtsklick im Projektmanager auf "Erfordert", dann .bpi-Datei auswählen. Findest du unter $(BDS)\release .



  • Ah, verstehe. Bis jetzt findet sich bei "Erfordert" lediglich die rtl.bpi.
    Hab jetzt die vcl.bpi hinzugefügt und neu kompiliert. Jetzt läuft das Programm.
    Supi.
    Werd ich mir speichern, als referenz, wenn ich die Packages mal brauche.
    Danke sehr. 🙂 🙂 🙂



  • Und wieder ich. 😕

    Nachdem mir audacia mit dem Code

    void setIsLibrary (void) {
        System::IsLibrary = true;
    }
    #pragma exit setIsLibrary 31
    

    sehr geholfen hat mein Problem mit der AccessViolation beim Beenden meiner Anwendung unter aktiver XP-Theme zu beheben, taucht dieses nun wieder auf.

    Ich habe in meiner Anwendung im Hauptmodul zwei Abfragen, mit denen ich prüfe ob die DLLs auch wirklich zu meiner Anwendung gehören, und eine die Abfrägt ob das Datamodul initialisiert ist. Beide Abfragen werfen jeweils mit

    throw Exception( <Fehlermeldung> )
    

    eine Exception um das Programm dann zu beenden. Diese Abfragen finden im Konstruktor des Hauptfensters statt. Nun wäre ich wieder für einen Tipp dankbar, um den Fehler auch bei einer Exception zu beheben.

    Oder gibt es noch eine bessere Möglichkeit ausser einer solchen Exception das Programm vorzeitig aus dem Konstruktor heraus zu beenden?

    Vielen Dank in Voraus, Netzschleicher



  • In meiner Beispielanwendung habe ich jetzt einfach mal im Konstruktor eine Exception geworfen. Das verursacht unter XP nach wie vor keine AV. Bitte zeig mal genau, was du gemacht hast. (Du kannst auch gerne wieder ein Projekt hochladen.)



  • Hallo audacia,

    folgende Konstellation:

    im Konstruktor des Hauptfensters ist folgende Abfrage:

    __fastcall Tfrmmain::Tfrmmain(TComponent* Owner) : TForm(Owner) {
    
    ...
    
    // Pruefen der Resourcen DLL
    CheckDllID(resID(), "res.dll", 55631002);  // ID-Nummer der Resource-DLL
    
    ...
    
    }
    

    weiter unten dann in der Source-Datei des Hauptfensters:

    void Tfrmmain::CheckDllID(int dllfunc, AnsiString DllName, int DllID) {
    	if (DllID != dllfunc) {
    		throw Exception ("DLL: " + DllName + " ist keine gültige Programm-DLL");
    	}
    }
    

    und genau da kracht es dann mit folgender Fehlermeldung:

    Exception-Klasse EAccessViolation mit Meldung 'Zugriffsverletzung bei Adresse 5B0F1531 in Modul 'uxtheme.dll'. Lesen von Adresse 00000014'. Prozess TPO.exe (2100)

    der Debugger bleibt in der Datei 'Forms.hpp' bei folgender Zeile stehen:

    /* TCustomForm.Destroy */ inline __fastcall virtual ~TForm(void) { }
    

    Unter Win2000, Win7 und WinXP mit klassischem Theme ist wiederum alles in Ordnung.



  • Das ist äquivalent zu meinem Programm, und ich habe dein Problem nicht.

    Bindest du die DLL wieder statisch ein?



  • Ja, die DLL wird weiterhin statisch eingebunden.
    In der DLL-Datei in welcher auch der

    int WINAPI DllEntryPoint
    

    steht, habe ich den kleinen Workaround von Dir für das schon gelöste Problem untergebracht.



  • Dann bitte ich um ein vollständiges Beispielprojekt, da ich es so nicht reproduzieren kann.



  • Oh mann ist das Peinlich. 😞 😞 😞

    Da hab ich mir selbst ein Bein gestellt. Aber ich bin jetzt dadurch drauf gekommen, als Du gesagt hast, das der Fehler bei Dir nicht auftritt. Hab dann selbst mal schnell ein kleines Projekt gemacht, und siehe da... kein Fehler.

    Ich hatte Dir doch geschrieben das der Debugger in der 'Forms.hpp' stehenbleibt. Das hab ich mir dann mal genauer angeschaut, nachdem ja in meinem kleinen Projekt auch kein Fehler auftrat.

    Ich musste dann feststellen, das in meiner Anwendung der Abbruch nur kommt wenn der Splashscreen eingeschaltet ist. Und das war mein Fehler, der Splashscreen war noch aktiv als ich die Exception geworfen habe. Hab jetzt in der Funktion in welcher der Throw steht noch der evtl. aktiven Splashscreen gelöscht, und nun ist wieder alles im Butter. 🙂

    Danke Dir trotzdem für Deine Mühe. War ein absolut dämlicher Fehler von mir.

    Grüße Netzschleicher


Anmelden zum Antworten