zlib installieren und nutzen

Thomasio

Erfahrenes Mitglied
Ich hätte gern zip/unzip Funktion in meiner Win32 Anwendung und nachdem ich jetzt den ganzen Tag damit zugebracht habe Google danach zu befragen komme ich wohl um zlib nicht herum.
Aber damit stehe ich wie die Kuh vorm Berg.
Quer übers Web finden sich 1000de von Usern, die alle danach fragen, wie man das installiert und/oder benutzt.
Die Antworten dazu verweisen alle auf dieselben Seiten, meistens das zlib Manual, aber da verstehe ich nur Bahnhof.
Bin ich wirklich so blöd, oder ist das für einen Anfänger tatsächlich so schwer zu begreifen?

Angefangen damit, dass der download von zlib.1.2.5 eine README-WIN32.txt enthält die beginnt mit "zlib 1.2.4 is a general purpose ..."
über Hinweise in der FAQ die besagen, dass die neueste Version 32bit und 64bit kompatibel ist, dann aber eine Makefile.gcc dabei ist, die vor 11 Jahren!! geschrieben wurde und natürlich nur 32bit unterstützt
und so Kleinigkeiten wie, man muss die .dll erstmal bilden, aber die Anleitung dazu besteht nur aus Befehlen für die Eingabeaufforderung, die davon ausgehen, dass man GCC und MAKE und sonstwas im Pfad hat, während ich Code::Blocks/MinGW-w64 verwende und überhaupt nichts davon im Pfad habe
bis hin zu (für mich) völlig unverständlichen Anmerkungen ala "For 64-bit Irix, deflate.c must be compiled without any optimization."

Wenns dann noch nicht reicht, selbst die (angeblich) einfachste Erklärung, wie man das benutzt (wenn man es denn installiert bekommt) besteht aus seitenlang Code mit Kommentaren ( http://zlib.net/zlib_how.html ) und selbst die beschränkt sich auf die Eingabeaufforderung und verschwendet kein Wort darüber, wie man das in einer Win32 (64bit) Anwendung mit fstream macht, von mehreren Dateien in einem zip gar nicht zu reden.

Ihr dürft gerne lachen und mich für blöd erklären, aber hat jemand Erbarmen und erklärt mir "für Doofe" wie man von

Download http://.... (ich weiss ja nicht mal welcher Download der Richtige ist für 64bit)

zu Funktionen kommt, die etwa heissen könnten

bool Compress("d:/files/*.*", "d:/zipfiles/Archiv.zip");
bool DeCompress("d:/zipfiles/Archiv.zip", "d:/files/");
 
Hmm, wenn du meinst, wie man eigene Programme gegen die zlib linkt, stellt sich als erstes die Frage: Welchen Compiler verwendest du?

Bei cygwin/mingw sollte das über die Shell => configure zu erledigen sein. Bei Visual Studio gibts im Ordner win32 ein Makefile.msc, welches man mit nmake (über die VS-Shell) verwenden kann, um eine static oder shared lib zu bauen. Bei static bekommst du einfach eine große .lib-Datei, die du gegen dein Programm linkst. Bei shared bekommst du eine kleine .lib mit einer .dll, auch hier linkst du die .lib gegen dein Programm, brauchst dann zum Ausführen des Programms aber die .dll.

Bei cygwin/mingw benutzt du wie schon geschrieben das configure-Script und anschließend make und make install. Anschließend kannst du mit ld oder gcc gegen die libz.a linken.
 
Du bist meinem Problem weit voraus, ich hänge schon viel weiter vorher.
Mal sehen, ob ich das beschreiben kann.

1) Ich suche mir über Google die zlib homepage, die findet sich unter http://www.zlib.net
Da gibt es zuerst mal einen Haufen Text samt Wiki Links zu den Autoren, ein Haufen Zeug über Änderungen zwischen den letzten paar Versionen, wo mir beim lesen schon übel wird, weil da von heftigen Bugs die Rede ist und empfohlen wird, wer noch eine alte Version hat, sollte schleunigst updaten.
Das ist von der ganzen Aufmachung her schon so gestaltet, dass es mich auf den ersten Blick gleich abschreckt, denn wer in der vorletzten Version noch heftige Bugs hatte, der hat in der letzten Version vermutlich auch nicht das Gelbe vom Ei.
Eine kurze Suche im Web zu Problemen mit zlib übertrifft meine schlimmsten Befürchtungen, aber was solls, es scheint ja nichts anderes zu geben, also weiter.

2) Mit etwas suchen und scrollen findet sich dann die Liste mit den Downloads, aber wozu 3 verschiedene Downloads die jeweils noch eine Mirror-Liste haben und dann auch noch die .dll separat auch wieder samt Mirror, was soll der Mist, sind die identisch oder muss ich jetzt die Richtige davon fiinden?

3) Ich lade einfach mal eine runter, packe sie aus und suche nach einer Readme oder Ähnlichem.
Die findet sich sogar, aber statt einer Anleitung zu Installation und Nutzung steht da nur lauter Müll drin, Perl und Phyton Support und so Zeug.
Immerhin findet sich ein Hinweis auf eine win32/DLL_FAQ.
Vorher finde ich aber noch eine FAQ, die ist identisch mit der FAQ Seite auf der zlib Homepage und enthält genau NULL von der Info die ich suche.
In der vielversprechenden DLL_FAQ steht dann zwar viel mehr Text, aber noch weniger nützliche Information, bzw. was da drin steht geht zum grossen Teil weit über meine Anfängerkenntnisse hinaus.
* The exported symbols are exclusively defined in the source
files "zlib.h" and "zlib.def", found in an official zlib
source distribution.
* The symbols are exported by name, not by ordinal.
* The exported names are undecorated.
* The calling convention of functions is "C" (CDECL).
* The ZLIB1.DLL binary is linked to MSVCRT.DLL.
Erklär mich für doof, aber ich Anfänger verstehe davon genau Bahnhof.
Und überhaupt, eine ZLIB1.DLL gibt es in dem Download nicht, nur einen Hinweis, dass man die von zlib.net runterladen kann.

3) Puhh, wenigstens gibt es die .dll als download, ich muss sie nicht selber bilden, also zurück zur zlib Homepage.
Runterladen, auspacken, Readme öffnen, da steht auch wieder nichts gescheites drin, aber in der USAGE.txt werde ich dann fündig.
Da steht unter "Using ZLIB1.DLL with gcc/MinGW":
2. Copy the supplied library file "zdll.lib" to "libzdll.a":
cp lib/zdll.lib lib/libzdll.a
HÄ? Bahnhof?
Ich wusste nicht, dass man aus einer .lib durch kopieren und umbenennen eine .a machen kann, und überhaupt, was ist der Sinn der zweiten Zeile?
2' Build the import library from the supplied "zlib.def":
dlltool -D zlib1.dll -d lib/zlib.def -l lib/libzdll.a
Ähem, ja, den Sinn verstehe ich sogar, aber das setzt voraus, dass ich MinGW/GCC im Pfad habe.
Habe ich aber nicht, denn MinGW-w64 läuft unter Win7 in der Code::Blocks IDE völlig ohne Path Einstellungen.
Ich habe mich dann daran versucht ohne Path Einstellungen die nötigen Dateien einfach alle ins selbe Verzeichnis zu kopieren, aber damit kann ich von einem Error zum Nächsten.
Irgendwann habe ich dann schlicht den ganzen Mist gelöscht und bin frustriert ins Bett gegangen.

4) Nächster Tage, neuer Versuch, ich finde in der FAQ
30.Is there some simpler, easier to read version of inflate I can look at to understand the deflate format?
Look in zlib's contrib/puff directory.
Gesagt, getan, aber ein Dutzend Fehlermeldungen später finde ich heraus, das ist in keiner Weise ein einfacherer Weg, zumindest nicht für mein Problem, denn es setzt voraus, dass ich mein Problem schon gelöst habe.

5) Ich ignoriere mein Problem erstmal, lese noch ein Stück weiter, finde unter http://zlib.net/zlib_how.html besagte einfache Anleitung, finde heraus, das ist eine Console Anwendung, wo die Dateinamen für stdin und stdout beim Programmaufruf an der Eingabeaufforderung eingegeben werden, von Win32 oder gar x64 oder gar multiple files überhaupt keine Rede.
Dafür findet sich ein Hinweis auf einen
" ... ugly hack required to avoid corruption of the input and output data on Windows/MS-DOS systems."
Tolle Sache, genau was ich brauche, noch mehr Probleme.
Als ich dann auch noch in der README-WIN32.txt gelesen habe, dass diese auf dem
"package zlib-1.2.4-win32-x86.zip"
basiert, obwohl dies doch die Version 1.2.5 sein soll war ich mehr als ein wenig verwirrt und als ich den Hinweis gefunden habe, dass das Ganze nur unter 32bit läuft, entgegen den Aussagen auf der zlib Homepage, die eindeutig 32bit und 64bit versprechen, habe ich es endgültig aufgegeben, bzw. dann bin ich hierher gekommen und habe meine Frage gepostet, denn an dieser Stelle bin ich mir nicht mal mehr sicher, was ich überhaupt runterladen muss, um eine funktionierende 64bit Version zu bekommen, von deren Verwendung gar nicht zu reden.
 
Wenn du dich selbst als Programmier-Anfänger bezeichnest, möchte ich anmerken, das zlib evtl. nicht das richtige für dich ist. zlib ist eine General-Purpose-Lib, das heißt, es ist vor allem so gestaltet, dass die Library für alles mögliche verwendet werden kann und dabei es keinen vorgegebenen Rahmen gibt, wie es einzusetzen ist. Ich habe damit einen Service geschrieben, der den Socket-Content komprimiert um den Output zu beschleunigen. Andere verwenden zlib um einen konkreten Algorithmus wie Gzip oder Bzip2 zu implementieren.

Ich denke, das du erstmal besser damit fährst, eine konkrete API zu verwenden. Ich denke da an das 7-zip-SDK oder auch Bzip2.
 
Jau, habe ich probiert, mit noch weniger Erfolg.
7zip SDK klingt ja toll, auch die Beschreibung auf der Webseite klingt vielversprechend.
Download und auspacken geht auch noch ganz einfach, aber was dann?
In den .txt Dateien die dabei liegen steht drin:

Usage: LZMA <e|d> inputFile outputFile [<switches>...]

Aber kein Wort über multiple files.
Dafür finden sich im Download 6 Unterverzeichnisse mit haufenweise Dateien, aber kein Wort darüber was das soll.
Ich vermute, da muss ich auch erstmal eine .dll bilden, aber wo und wie steht nicht dabei.

Auf er Bzip2 Seite gibt es immerhin gleich zu Anfang einen Absatz über Installation, aber der Link zur "Package List" fürhrt zu ERROR 404.
Unter Usage reden die dann auch wieder von DOS-box, da bezweifle ich, ob es das überhaupt in 64bit gibt und wenn der Download eh nicht geht, kann ich eh nichts machen.
 
Ok, also ich versuch mal, zu beschreiben, was zu tun wäre. Du brauchst bei Bzip2 eigentlich nur 2 Zip-Files.

1. Das Binaries-Zip; es beinhaltet die Header-Files und die Bibliotheken zum Linken. Zudem befindet sich in dem Archiv eine DLL, sprich es ist alles vorhanden, was du brauchst um Projekte gegen die bzip2.dll zu linken und laufen zu lassen. Wenn du eine MinGW-kompatible Umgebung hast, entpackst du das Zip-File einfach dort hin, wo sich die bin, lib, include, share, usw Ordner von MinGW schon liegen. Gern können wir das auch noch detailierter besprechen. Das Archiv ist jedenfalls das hier:

http://gnuwin32.sourceforge.net/downlinks/bzip2-bin-zip.php


2. Das Documentation-Zip beinhaltet ein prima PDF, auch eine HTML-Anleitung, wie man bzip2 verwendet. Das bringt dir aber erst was, wenn du verstanden hast, wie ein Tool-Chain arbeitet. Das ist nämlich dein derzeitiges Problem.

3. Stell dir die Frage, was eigentlich das Problem ist. Du verwendest also Code::Blocks, welches ich nicht kenne, aber grundsätzlich eine MinGW-IDE zu sein scheint. Das hast du bei dir lokal irgendwo installiert, ich geh mal von "C:\Programme\CodeBlocks" aus. Dort wird es vermutlich einen Ordner "bin" geben, in dem die ganzen Exe-Dateien und Dlls drin liegen. Dann hats dort vermutlich einen include-Ordner, in dem die Header-Files liegen. Außerdem wirds dort einen Ordner lib geben, in dem die ganzen Libraries liegen, die man so linken kann, das sind die .a-Dateien, die man beim Compiler-Lauf mit -l[libraryname] angibt.

Wenn du neue Libraries "installieren" willst, hast du eigentlich immer 2 Dinge zu tun (manchmal sind es 3).

- Kopiere die Header-Files (.h-Dateien) in den Ordner "include"
- Kopiere die Link-Libraries (.a-Dateien) in den Ordner "lib"
- (evtl.:) Kopiere die DLL (falls vorhanden) in den Ordner "bin"

Shared Library
DLLs gibt es nur dann, wenn es sich um eine sog. Shared-Libary handelt. Dann muss diese DLL-Datei auf dem Ziel-System auch existieren, auf dem das Programm ausgeführt werden soll.

Static Library
Wird nur beim Linken benötigt, der komplette Code der Bibliothek wird mit in das Programm aufgenommen, es sind keine weiteren Ressourcen auf dem Ziel-System nötig.



Vergiss das mit Dos-Box, das brauchst du nicht. Du brauchst "nur"

- Einen Bauplan über die Architektur der Bibliothek (.h-Datei)
- Die Bibliothek selbst (im Falle von MinGW als .a-Datei, im Falle von VisualStudio sind es .lib-Dateien)
- evtl. eine DLL, wenn es eine shared Library ist.


Ich hoffe, es ist dir jetzt etwas klarer, wie das funktioniert.
 
So langsam kommt Licht ins Dunkel.
Code::Blocks ist eine cross platform IDE für viele Compiler, inkl. MinGW, braucht keinerlei Installation, keinerlei Systemeinstellungen, sondern funktioniert als 1:1 Kopie, ich habe dafür einen Ordner
D:\CodeBlocks\
Code::Blocks hat eine auto detect Funktion für diverse Compiler, ich muss nur MinGW-w64 runterladen, irgendwohin entpacken und C::B den passenden Verzeichnisnamen geben, darum habe ich auch für MinGW keinerlei Installation, keinerlei Systemeinstellungen, sondern eine einfache 1:1 Kopie unter
D:\MinGW64\
Deine Erklärung mit den Ordnern include lib und bin war mir allerdings schon klar, auch weiss ich, dass MinGW .dll´s direkt linken kann, ich mir also aussuchen kann, ob ich eine .dll oder eine .a verwenden will.

Das grösste Problem bisher war, dass es im Download weder eine .dll noch eine .a gab, höchstens eine (für mich) sehr technische Erklärung, wie man die in er Eingabeaufforderung selber bilden kann, was bei mir nicht geht, weil ich die nötigen Suchpfade nicht im System eingestellt habe.

Im Download den du mir jetzt gegeben hast findet sich jetzt sogar beides, das ist doch schon mal was, allerdings finde ich da jetzt mehr als ich suche und kann mich nicht entscheiden, was ich davon brauche.
\bin\bzip2.dll
\lib\libbz2.a
\lib\libbz2.dll.a
Und überhaupt, sind die alle 32bit und 64bit kompatibel, brauche ich dafür nicht 2 Verschiedene?

Das könnte man zur Not einfach ausprobieren, aber dann kommt die praktische Anwendung.
Das manual.pdf habe ich mir zu Gemüte geführt, auch in der HTML Version.
Da stehen Sachen drin wie:

3.3.4. BZ2_bzDecompressInit
int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
Prepares for decompression. As with BZ2_bzCompressInit, a bz_stream record should be allocated and initialised before the call. Fields bzalloc, bzfree and opaque should be set if a custom memory allocator is required, or made NULL for the normal malloc / free routines. Upon return, the internal state will have been initialised, and total_in and total_out will be zero.

3.3.5. BZ2_bzDecompress
int BZ2_bzDecompress ( bz_stream *strm );
Provides more input and/out output buffer space for the library. The caller maintains input and output buffers, and uses BZ2_bzDecompress to transfer data between them.

Ich weiss ja, dass ich mich bei diesen Sachen gerne noch blöder anstelle als ich eh schon bin, aber wie ich aus diesem Fachchinesisch eine Funktion machen soll, die

Entpacke alle Dateien aus
D:\archive\test.zip
nach
D:\irgendwas\

macht, ist mir völlig Bahnhof.
 
Also, zunächst musst du dein Projekt so einstellen, das es gegen die libbz2.dll.a linkt. Dazu hast du Projekt-Einstellungen, müsstest dort als Library libbz2.dll.a linken (siehe Anhang).

Zu deinem Anliegen:

bzip2 ist ein reiner Komprimier- und kein Archivier-Algorithmus. Es wird gern in Kombination zu tar (Tape-Archiver) verwendet. Vielleicht erstmal eine kleine Erklärung:

- Archivieren ist das Ergebnis, aus mehreren einzelnen Dateien einen Container zu erstellen, in dem alle Dateien in unkomprimierter Form abgelegt sind.
- Komprimieren fast eine einzelne Datei so zusammen, das sie weniger Speicher auf einem persistenten Medium benötigt.

Winzip, Winrar, 7-zip und wie sie alle heißen mögen erledigen also beide Dinge, sobald man mehr als nur eine Datei zu einem Archiv komprimiert. Zuerst wird der Container erzeugt, die Dateien darin abgelegt und anschließend dieser Container komprimiert.

Da Bzip2 nur ein Komprimier-Algo ist, kannst du damit nicht mehrere Dateien zu einer zusammen fassen. Das geht nur mit Tar, Zip, Rar oder bspw. auch mit 7z.

Tut mir leid, dich enttäuschen zu müssen, mit Bzip2 kannst du keine .zip-Archive erstellen, die dann in Winzip oder dergleichen geöffnet werden können, geschweige denn, mehrere Dateien komprimieren. Das geht im Übrigen mit zlib auch nicht. Du brauchst also etwas wie eine Library, die

- .zip-Dateien erstellen kann (könnte schwierig werden, da .zip IMHO durch Patente geschützt ist)
- .7z-Dateien erstellen kann (mit Hilfe des 7zip-SDK z.B.)

Auch wenn ich dir hier keine Out-Of-The-Box-Lösung präsentieren kann, weil das Thema sehr konfus sein kann, hoffe ich, du kannst da was draus lernen.

Ich würde es so angehen: Versuche, das 7zip-SDK zu verstehen. Ich könnte dir lediglich anbieten, das lzmalib-Projekt aus dem Ordner C\Util\lzmalib für Visual-Studio zu kompilieren, für MinGW/CodeBlocks müsstest du das entweder allein hinbekommen und du suchst im Netz nach einer Anleitung, das zu kompilieren oder jemand anders erledigt das für dich. Wobei ich dir raten würde, das selbst zu versuchen, denn du lernst, mit den Tools umzugehen, die im Hintergrund werkeln - eigentlich sollte man damit anfangen ;-)

Versteh mich nicht falsch, ich will dir sicher kein Wissen vorenthalten, im Gegenteil, ich will dir die Richtung zeigen, die du gehen solltest, um dir selbst zu helfen.

Edith meint, dass der Anhang noch fehlte.
 

Anhänge

  • codeblocks.libs.png
    codeblocks.libs.png
    23,6 KB · Aufrufe: 21
Ich bin dir ganz extrem dankbar, dass du dir hier die Mühe mit mir machst.
Ich denke ich habe so einiges verstanden, zumindest habe ich soviel kapiert, dass das Ganze für meine Zwecke viel komplizierter wird als mir lieb ist, insbesondere, weil ich nur genau EINE Funktion für EIN ganz bestimmtes Projekt überhaupt brauche.

Vielleicht mal ganz von vorne? Vielleicht gibt es eine viel einfachere Lösung, wenn man das Ganze auf diesen einen Fall beschränkt?

Ich habe einen Ordner voll Dateien, aus dem ich ein gepacktes Archiv mache, damit ich es auf meiner Homepage als Download anbieten kann.
Mir ist völlig schnurz welches Format dieses Archiv haben soll, .zip oder .7z, selbstextrahierende .exe oder sonstwas, ich erstelle es selber, also kann ich es mir aussuchen.

Meine Win32 Anwendung läd das Archiv via WinInet runter und speichert es auf der Festplatte (das funktioniert prima).

Jetzt soll meine Anwendung das Archiv mit der original Struktur von Unterordnern entpacken, unter der Bedingung, dass dabei keine Eingabe vom User nötig ist und allles was dazu nötig ist entweder auf jedem Windows-PC (ab Win2000) existiert oder von der Anwendung mitgebracht wird, sprich das Ganze soll unbedingt auf jedem Windows-PC funktionieren, auch wenn der User nichts weiter installiert hat als irgendein standard Windows.

Von mir aus kann da kurz eine Console aufpoppen die das übernimmt, solange das automatisch geht ist das kein Problem, ich bräuchte nur die Syntax für den passenden Befehl.
 
Zurück