AnsiString::LoadStr aus eigener Funktion -> Zugriffsverletzungen NUR im DebugMode [gelöst]



  • Hallo Gemeinschaft,

    ich arbeite an einem Projekt im DebugMode in BDS2006. Zur Laufzeit wird aus dem Hauptformular heraus ein Formular instanziiert (ist unter "Projekt > Optionen > Formulare" nicht in der Spalte "Automatisch erstellen") und mit ShowModal() angezeigt.
    Der Aufruf des Konstruktor des neuen Formular initialisiert eine Member-Variable (HINSTANCE * const hi), die als Zeiger auf eine - mit LoadLibrary("DllName") ermittelte - HINSTANCE-Variable dient.
    Soweit, sogut.
    Im FormShow() des instanziierten Formular werden nun Strings aus einer Dll geladen. Dies geschieht mittels ***AnsiString::LoadStr(hi, Id)**, wobei Id über Makros angegeben wird (zB. #define GWA_LBL_SP_ 1951).
    Das funktioniert gut, nur kommt es zu Zugriffsverletzungen beim Laden von Strings aus der Dll, wenn ich die Lade-Funktion in eine eigene Funktion packe, um einen übersichtlicheren Quelltext zu erhalten:

    AnsiString TForm::DllString(int const & Id)
    {
    	return(AnsiString::LoadStr(*hi, Id));
    }
    //------------------------------------------------------------------------------
    

    Das wiederum nur, wenn die Anwendung im Debug-Mode erstellt wurde! 😕
    Im ReleaseMode werden alle Strings augenscheinlich problemlos geladen. Ich mache mir jedoch Sorgen, dass ich etwas falsch mache...

    Wo kann ich Ansetzen, um das Problem einzugrenzen und ggf. zu lösen? Gibt es überhaupt ein Problem, oder läuft da was im BDS nicht richtig? Ist evtl. nur eine Einstellung im DebugMode gegenüber dem ReleaseMode falsch?

    Vielen Dank für jede Anregung!

    MfG

    Edit: [Gelöst] in Thread-Titel ergänzt...



  • Ich hatte sowas ähnliches schonmal wenn im Compiler die Code Optimierung Ausgeschaltet ist.



  • Danke für den Hinweis, leider erfolglos 😞

    Sowohl im ReleaseMode als auch DebugMode ist die Codeoptimierung auf "schnellstmöglichen Quelltext" gestellt. Ich habe beide Modi gleichzeitig mal probehalber auf "kleinstmöglichen Quelltext" und danach auf "keine Optimierung" gestellt: Es ändert sich Nichts - Im DebugMode kommt es zur Zugriffsverletzung, im ReleaseMode nicht.



  • Wie wärs, wenn du mal mit dem Debugger durch gehst? Setze einen Haltepunkt in deine Funktion und schau dir deine Variablen an.
    Warum ist hi ein Zeiger?
    Warum übergibst du Id als konstante Referenz.



  • Das mit dem Debugger hatte ich schon, allerdings konnte ich das Problem nicht identifizieren: Ich hatte eine Id gefunden, bei der die Zugriffsverletzung auftrat. Den Aufruf habe ich testweise entfernt, dann trat die Zugriffsverletzung bei einer vorher benutzten Id auf, mit der aus davor kein Problem gab. Und das, wie gesagt, nur im DebugMode und nur mit der eigenen Funktion! Das machte für mich keinen Sinn und ich hab die Haltepunkt-Aktion verworfen.

    hi ist ein Zeiger weil... warum denn nicht? Macht es einen Unterschied, ob ich beim Aufruf von AnsiString::LoadStr() einen Zeiger auf Hinstance dereferenziere, oder Hinstance direkt eintrage? Oh... ich sehe gerade, dass AnsiString::LoadStr() einen Zeiger haben will; also ohne dereferenzieren... Bringt auch eine Zugriffsverletzung im DebugMode und nun sogar im ReleaseMode 😞
    Mache ich etwas falsch beim Aufruf von AnsiString::LoadStr() ? Hat doch immer funktioniert...

    Id als konstante Referenz, weil ich in meiner Funktion Id nicht ändere, sondern nur den Wert einmal lese... Angeblich geht das ja auch schneller, da keine Kopie angelegt werden muss. Ist das nicht Ok?



  • Laut meiner Hilfe will LoadStr keinen Zeiger. Zeiger würde ich sowieso nur verwenden wenn sie absolut nötig sind und das ist bei modernen C++ eher selten.
    Bei VCL-Klassen muss man sie natürlich verwenden.
    Zeiger können auf ungültigen Speicher zeigen - Fehler.
    Hier ist kein Zeiger nötig - also weg damit und wir haben eine mögliche Fehlerquelle weniger.

    Zur Id.
    Die Kopie eines ints hat etwa den gleichen Aufwand wie die Übergabe einer Referenz (oder weniger). Deswegen ebenfalls nicht nötig.
    Allgemein übergibt man PODs (int, double, char, Zeiger) normalerweise als Kopie.



  • Braunstein schrieb:

    Laut meiner Hilfe will LoadStr keinen Zeiger. [...]

    Und wie muss ich dann den 1. Parameter interpretieren:

    BDS2006-Hilfe schrieb:

    AnsiString LoadStr (HINSTANCE__ * hInstance, int ident);
    

    😕

    So, Id als Kopie übergeben und hInstance direkt angegeben -> keine Zugriffsverletzung mehr im DebugMode 🙂 Vielen Dank! 👍

    Trotz allem habe ich es wegen dem Ausdruck in der Hilfe noch nicht ganz kapiert (Zeiger oder nicht Zeiger?)... 😞



  • So wie es aussieht kann HINSTANCE ein typedef auf HINSTANCE__* sein.
    Dann wäre beides identisch.
    In der BCB5-Hilfe und in der GC2007-Hilfe steht dieses

    static __fastcall AnsiString LoadStr(HINSTANCE hInstance, int ident);
    

    Welche Builder Version hast du denn?



  • Ich arbeite mit Borland Developer Studio 2006 (siehe mein Eröffnungspost und meine Signatur 😉 ).



  • Das habe ich doch komplett übersehen. 😞


Log in to reply