Jedi Code Library - 7Zip mit JclCompression - wie?



  • Hallo Zusammen,

    vielleicht eines vorweg - ich bin nur Hobbyprogrammierer, und das noch nicht so lange. Ich versuche seit einigen Tagen mit dem C++-Builder vom Rad Studio 2009 Dateien auf der Festplatte mit 7Zip zu komprimieren - ich bekomme es einfach nicht hin.

    Die Installation der Jedi Code Library funktionierte ohne Probleme, auch das einbinden der JCL in meinen Code

    #include <jclcompression.hpp>
    using namespace Jclcompression;
    

    klappt problemlos.

    Aber wie gehts weiter?
    Ich vermute ich muss ein Objekt erzeugen, und diesem dann Kompressionsmethode, Ausgabepfad und -name mitteilen sowie Dateien zum komprimieren übergeben.

    Nur, wie mache ich das? Alle meine Versuche wurden mit Fehlermeldungen wie "Kann keine Instanz abstrakter Klassen erzeugen" (oder so ähnlich) quittiert.

    Hat jemand hier im Forum Erfahrungen beim Nutzen der JCL, vllt. sogar mit 7-zip Kompression unter C++?

    viele Grüße,
    B

    PS: Das LZMA-SDK und die 7zip UI bekomme ich unter rad2009 leider auch nicht zum Laufen.



  • auf der Seite wo es den Code gibt, sind doch sicher Beispiele vorhanden o.ä.

    greetz KN4CK3R



  • Nein, habe ich leider nicht gefunden. Selbst in dem 8000 Seiten starken PDF-File habe ich leider keine Codebeispiele gefunden.
    Vielleicht liegt es ja daran, dass die 7Zip-Unterstützung noch sehr neu ist.

    Ich ärgere mich nur über mich selbst, weil ich es nicht hinbekomme. 😡



  • Hallo,

    hier nochmal ein paar Details, damit man mein Problem besser nachvollziehen kann:
    Im Netz habe ich folgendes Pascal (Delphi) - Beispiel gefunden:

    procedure CompressStream(const ASourceStream,ADestinationStream: TStream);
    var
      Archive : TJclCompressArchive;
    begin
      ADestinationStream.Position := 0;
      Archive := TJclGZipCompressArchive.Create(ADestinationStream,0,False);
      try
        Archive.AddFile('Stream0',ASourceStream,False );
        Archive.Items[0].LastWriteTime := LocalDateTimeToFileTime(Now);
        Archive.Compress;
      finally
        Archive.Free;
      end;
    end;
    

    Das wollte ich dann einfach in C++ umsetzen:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <jclcompression.hpp>
    #include "Unit1.h"
    using namespace Jclcompression;
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    TJclCompressArchive archive = new TJclCompressArchive();
    }
    //---------------------------------------------------------------------------
    

    Die Fehlermeldungen beim compilieren sind Folgende:

    [BCC32 Fehler] Unit1.cpp(20): E2352 Instanz der abstrakten Klasse 'TJclCompressArchive' kann nicht erzeugt werden
    [BCC32 Fehler] Unit1.cpp(20): E2353 Klasse 'TJclCompressArchive' ist abstrakt, weil '_fastcall TJclCompressionArchive::GetItemClass() = 0'
    

    Vielleicht liegt der Fehler, den ich mache ja an anderer Stelle?

    Grüße,
    Borath



  • void __fastcall TForm1::Button1Click(TObject *Sender)
    {
       // archive ist ein Pointer!
       TJclCompressArchive* archive = new TJclCompressArchive();
    
       // probier mal das hier:
       TJclCompressArchive* archive = new TJclGZipCompressArchive();
    }
    

    Fällt dir der Unterschied zwischen dem Delphi und deinem Quelltext nicht auf? TJclCompressArchive scheint eine abstrakte Basisklasse zu sein, die von TJclGZipCompressArchive implementiert wird.



  • Hallo DocShoe,

    das ist mit tatsächlich nicht aufgefallen!
    Vielen Dank für den Hinweis.

    Dein Codesample führt nun zu einer neuen Fehlermeldung:

    [BCC32 Fehler] Unit1.cpp(20): E2285 Keine Übereinstimmung für 'TJclGZipCompressArchive::TJclGZipCompressArchive()' gefunden
    

    Wenn ich die Fehlermeldung richtig interpretiere, dann scheint es da ein Problem mit Abhängigkeiten zu geben...

    Muss ich da noch etwas beim includieren von JCL beachten?

    viele Grüße,
    Borath



  • Ich habe keine Ahnung von der JCL, aber (bitte guck dir doch den Delphi Quelltext genau an!) der TJclGZipCompressArchive Konstruktor erwartet 3 Parameter. Ich hab´s erst später gesehen und daher meinen Quelltext nicht korrigiert. Sollte aber eigentlich sofort in´s Auge springen.



  • Hallo,

    vielen Dank für die Hilfe, welche mir hier zuteil wurde.
    Nach einigen Problemen (32Bit Rad2009 und 64Bit-OS + 64Bit-7z.dll) läuft es nun!

    viele Grüße!!
    Borath



  • Hallo zusammen

    @Borath
    Da mich dieses Thema demnächst vermutlich auch treffen wird, wäre es schön, wenn Du uns an deiner Lösung teilhaben läßt.

    MfG Stephan



  • Hallo Stephan,

    um ehrlich zu sein, habe ich es noch nicht geschafft, eine Datei zu 7z-komprimieren, aber die Probleme, die ich noch zu lösen habe, gehören nicht mehr hier ins Forum, sondern ins Forum von JCL (sofern die eins haben, bin noch nicht dazu gekommen).

    Der folgende Code kompiliert zwar ohne zu murren, aber beim Aufruf der Compress()-Methode wird eine Zugriffsverletzung im Modul jcl120.bpl ausgelöst.

    Ich bin mir nicht im klaren, ob ich vielleicht eine falsche 7z.dll Version habe, oder ob ich alles richtig mache - immerhin gibt es Null Dokumentation zu diesem Thema.

    Falls es dich weiterbringt, hier mein Code, den ich soweit habe:

    TFileStream *FileStream = new TFileStream("test.7z", fmCreate | fmOpenReadWrite);
    	 TFileStream *Source = new TFileStream("test.log", fmOpenRead);
    
    	 //TJclCompressionArchive | TJcl7zCompressArchive
    	 TJclGZipCompressArchive * archive;
    
    	 archive=new TJclGZipCompressArchive(FileStream,0,false);
    
    	 archive->AddFile("Stream0",Source,false);
    	 archive->Compress();
    

    Achja, bei der Methode AddFile wird als erster Parameter ein Package erwartet - keine Ahnung, was es damit auf sich hat.

    Falls du, oder wer anders an dieser Stelle weiterkommt, bitte hier in diesem Topic posten, wie es geht. Ich denke, da wären eine Menge Leute dankbar.

    viele Grüße,
    B



  • Hallo nochmal,

    ich dämlicher Flanders hab nicht genau gelesen, der erste Parameter ist kein "packet name" sondern ein "packed name".

    ich hab nun folgendes versucht:

    //archive->AddFile("Stream0",Source,false);
    	 archive->AddFile("test.log.packed","test.log") ;
    	 ShowMessage(archive->ItemCount);
    	 ShowMessage(archive->Items[0]->FileName);
    	 archive->Compress();
    	 archive->Free();
    

    Hilft aber nix, immer noch der gleiche Fehler.

    Grüße,
    B


Anmelden zum Antworten