VC++ 6.0 debuggen



  • @gjk Ja, sorry. Habe ich natürlich schon gemacht; aber gefunden habe ich, dass etwa beim erstellen des Projektes eine falsche ->Auswahl getroffen wurde. Das könnte ich ja jetzt gar nicht mehr ändern...!
    Es ist aber ->Win32 Anwendung.
    Die komplette Fehlermeldung ist nun: EdiNrPrintDlg.obj : error LNK2001: unresolved external symbol __imp__LlJobClose@4
    Und das 20x mit verschiedenen Symbolen



  • Kompiliert (und linkt) denn die Release-Version? Dann schau dort in den Linker-Einstellungen nach, welche Libs noch dazugelinkt werden (und übernimm diese für den Debug-Build).



  • @gjk

    Die komplette Fehlermeldung ist nun: EdiNrPrintDlg.obj : error LNK2001: unresolved external symbol __imp__LlJobClose@4

    Nutzt du die Lib "List & Label 27"?

    Ich habe mal kurz im Internet gestöbert und bin über diese Lib gestolpert. In der Doku dazu steht du musst die Datei cmll27.lib einbinden. Ist das bei dir der Fall?



  • @Quiche-Lorraine Ohh. Das ist ja interessant: in diesem Prog wird L6L 8.0 benutzt. Vielleicht ist es da ähnlich...
    Probiere ich aus.
    Vielen Dank



  • @gjk Super! Das war der Tipp; jetzt lässt sich das Prog schon mal kompilieren. Und es hält auch am Breakpoint an. Wenn ich aber F10 für Weiter drücke kommt eine neue Meldung:
    First-chance exception in EdiNrPrint.exe (OLE32.DLL): 0xC0000005: Access Violation.
    und VC stürzt völlig ab.



  • @gjk
    Ja, da haste den Grund doch schon gefunden. Per Einzelschritt weiterdebuggen und/oder Funktionsparameter prüfen.



  • @gjk sagte in VC++ 6.0 debuggen:

    Ohh. Das ist ja interessant: in diesem Prog wird L6L 8.0 benutzt. Vielleicht ist es da ähnlich...

    Pass bitte auf das du beide Versionen nicht miteinander vermischt. DLL, Lib und Header müssen für die gleiche Version nutzen!

    Ansonsten, debuggen, live Parameter prüfen und mit der Dokumentation vergleichen.



  • @Quiche-Lorraine Vielen Dank; du hast mir schon sehr viel weiter geholfen!
    Ich verstehe nur nicht:
    -> Prog lässt sich in Debug kompilieren
    -> F5 und hält dann auch an Breakpoint an
    -> jetzt mit F10 weiter ---> gibt Access violation!
    was meinst du genau soll ich noch beachten?



  • @gjk sagte in VC++ 6.0 debuggen:

    Ich verstehe nur nicht:
    -> Prog lässt sich in Debug kompilieren
    -> F5 und hält dann auch an Breakpoint an
    -> jetzt mit F10 weiter ---> gibt Access violation!
    was meinst du genau soll ich noch beachten?

    Die Vorgehensweise ist recht einfach. Du musst nachschauen welche Funktion du an der Stelle aufrufst, welche Parameter du der Funktion (siehe Debugger) übergibst und welche Parameter die Funktion wünscht (Doku).

    Ein Klassiker bezüglich Access Violation ist beispielsweise ein nicht initialisierter Pointer.



  • @Quiche-Lorraine

    Oder ein falsches Speicherlayout. Das kann viele Gründe haben.



  • @DocShoe Moin. Das mit der Funktion habe ich ja verstanden und das kann ich ausschließen. Es geht auch nicht, dass ich mit F10 z.B. in einer Schleife cruisen kann. Was ist gemeint mit Speicherlayout oder nach was kann ich da googeln?



  • @gjk
    Am Besten du postest mal den Abschnitt des Quellcodes mit dem Funktionsaufruf.

    Manchmal unterscheiden sich Strukturen/Klassen in Debug- und Release-Version, weil zB im Debug Modus zusätzliche Member mit Debug-Informationen existieren. Wenn man beim Bauen dann zwar die Debug-Header verwendet aber gegen die Release-Bibliotheken linkt stimmen die Offsets für die Member nicht und man erhält einen Speicherzugriffsfehler.

    Das kann ein Grund für deinen Fehler sein.



  • Du gibst dir echt Mühe mit mir. Danke!
    Hier ein Ausschnitt. Ich stehe -> und will mit F10 weiter debuggen.:
    void CEdiNrPrintDlg::EdiDateienZeigen(int jahr, int monat)
    {
    CString Pfad;
    SetzeEdiPfad();
    CFileFind cff;
    BOOL bGefunden;
    CString Dateiname;
    //in 2-stellige Angabe umwandeln
    jahr = jahr % 100;
    m_DatDir.Format("%s%02d%02d\Data",m_EdiDir,jahr,monat);
    m_lstNummern.ResetContent();
    m_bnDrucken.EnableWindow(FALSE);
    m_bnELSDrucken.EnableWindow(FALSE);
    m_bnEtikett.EnableWindow(FALSE);

    m_lstDateien.ResetContent();
    Pfad.Format("%s%02d%02d\\Data\\*ABRP.dat",m_EdiDir,jahr,monat);
    

    -> bGefunden = cff.FindFile(Pfad);
    while( bGefunden) {
    bGefunden = cff.FindNextFile();
    Dateiname = cff.GetFileName();
    m_lstDateien.AddString(Dateiname);
    }

    }
    Dann kommt ERROR



  • @gjk sagte in VC++ 6.0 debuggen:

    while( bGefunden) {
    bGefunden = cff.FindNextFile();
    Dateiname = cff.GetFileName();
    m_lstDateien.AddString(Dateiname);
    }

    Das sieht doch sehr verdächtig aus. Egal ob eine Datei gefunden wurde oder nicht, du liest ihren Dateinamen aus. Die Zeile bGefunden = cff.FindNextFile(); gehört nach unten in die Schleife.

    Edit: ich nehme dies zurück, nachdem ich in die Doku geschaut habe. Das scheint so richtig zu sein, wie du es gemacht hast. Finde ich sehr kontraintuitiv. Aber ich arbeite auch nicht mit dem CFindFile. Hätte es dennoch anders erwartet.



  • Wie sieht denn der Inhalt von Pfad zum Zeitpunkt des Aufrufs aus, ist das ein gültiger Pfad?
    Bei der Formatierung von m_DatDir fehlt jedenfalls ein Bäcksläsch, nicht dass Windows/MFC über einen ungültigen Pfadnamen stolpert.

    PS:
    Bitte den Code über Code-Tags formatieren



  • @wob Es funktioniert soweit ja auch alles; es ist auch nur exemplarischer Code. Das Problem des debuggens taucht überall auf.
    Ich will/muss nur ein paar Parameter ändern; dazu will ich die Reihenfolge der Aufrufe betrachten.



  • @gjk sagte in VC++ 6.0 debuggen:

    @wob Es funktioniert soweit ja auch alles; es ist auch nur exemplarischer Code. Das Problem des debuggens taucht überall auf.
    Ich will/muss nur ein paar Parameter ändern; dazu will ich die Reihenfolge der Aufrufe betrachten.

    Ich habs auch schon zurückgenommen. Ich kenne die FindFirst/FindNext noch von Turbo Pascal... Dort und auch in der WinAPI FindFirstFileW wäre das, was ich geschrieben hatte, richtig gewesen.



  • @wob sagte in VC++ 6.0 debuggen:

    while( bGefunden) {
    bGefunden = cff.FindNextFile();
    Dateiname = cff.GetFileName();
    m_lstDateien.AddString(Dateiname);
    }

    Wäre es da nicht besser dies folgendermaßen zu erledigen?

    void CEdiNrPrintDlg::EdiDateienZeigen(int jahr, int monat)
    {
      CString Pfad;
      SetzeEdiPfad();
      CFileFind cff;
      BOOL bGefunden;
      CString Dateiname;
      //in 2-stellige Angabe umwandeln
      jahr = jahr % 100;
      m_DatDir.Format("%s%02d%02d\Data",m_EdiDir,jahr,monat);
      m_lstNummern.ResetContent();
      m_bnDrucken.EnableWindow(FALSE);
      m_bnELSDrucken.EnableWindow(FALSE);
      m_bnEtikett.EnableWindow(FALSE);
    
      m_lstDateien.ResetContent();
      Pfad.Format("%s%02d%02d\\Data\\*ABRP.dat",m_EdiDir,jahr,monat);
     bGefunden = cff.FindFile(Pfad);
     while(cff.FindNextFile()) {  
       Dateiname = cff.GetFileName();
       m_lstDateien.AddString(Dateiname);
     }
    }
    

    Ich traue der Funktion cff.GetFileName() nicht so recht, wenn cff.FindNextFile() false zurückliefert.



  • @Quiche-Lorraine sagte in VC++ 6.0 debuggen:

    Ich traue der Funktion cff.GetFileName() nicht so recht, wenn cff.FindNextFile() false zurückliefert.

    Ist aber richtig laut Doku. Siehe Beispiel hier: https://docs.microsoft.com/de-de/cpp/mfc/reference/cfilefind-class?view=msvc-170

    Laut https://docs.microsoft.com/de-de/cpp/mfc/reference/cfilefind-class?view=msvc-170#findnextfile returnt das 0 bei Fehler oder wenn die letzte Datei gefunden wurde. Wer denkt sich sowas aus?! Man muss also eigentlich immer GetLastError aufrufen.

    Wie gesagt, war auch kontraintuitiv für mich, aber damit scheine ich den Thread in die falsche Richtung gelenkt zu haben. Sorry!

    Was mir nur unklar ist, wie funktioniert dies praktisch, wenn 0 Dateien gefunden werden? Vielleicht ist das auch das Problem?

    Ungleich 0 (null), wenn weitere Dateien vorhanden sind. 0 (null), wenn es sich bei der gefundenen Datei um die letzte Datei im Verzeichnis handelt oder wenn ein Fehler aufgetreten ist. Um erweiterte Fehlerinformationen abzurufen, rufen Sie die Win32-Funktion GetLastErrorauf. Wenn die gefundene Datei die letzte Datei im Verzeichnis ist oder keine übereinstimmenden Dateien gefunden werden können, gibt die GetLastError Funktion zurück ERROR_NO_MORE_FILES.

    Wie unterscheide ich "letzte Datei" von "es gibt gar keine Datei"?!



  • Dann sollte das so aussehen?

    void CEdiNrPrintDlg::EdiDateienZeigen(int jahr, int monat)
    {
       CString Pfad;
       Pfad.Format("%s%02d%02d\\Data\\*ABRP.dat",m_EdiDir,jahr,monat);
       if( cff.FindFile( Pfad ) )
       {
          while( cff.FindNextFile() )
          {
             ...
          }
       }
    }
    

Anmelden zum Antworten