Using zlib under windows mingw

2020-08-16 04:11发布

问题:

I can't seem to get zlib to do anything on mingw under windows.

I downloaded zlib @ http://sourceforge.net/projects/mingw/files_beta/MinGW/zlib/zlib-1.2.3-1-mingw32/ and put the header and lib files in the right place.

Simple code like:

#include <stdlib.h>
#include <stdio.h>

#include "zlib.h"

int main(int argc, char *argv[])
{
    long a;
    char buffer[1024];
    a = 1024;
    compress(buffer,&a,"testing",7);
    return 0;
}

compiled:

gcc test.c -lzlib -Wall -o test.exe

Compiles fine. However the exe crashes at the compress function. Any ideas?

回答1:

I recommend using MSYS2 for this kind of thing. These instructions assume you want to compile a 64-bit program, but they can easily be modified for 32-bit.

After installing MSYS2, run the "MinGW-w64 Win64 Shell" shortcut in your Start Menu. Install the 64-bit toolchain by running:

pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-zlib

Then compile your code by running something like this:

gcc test.c -lz -o test

I did not check your code carefully, but I was able to run your code without any crashing, so your code might be OK. Your code also gives no output so it's hard to tell if it really worked.



回答2:

Looking at the zlib manual it says:

ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
                           const Bytef *source, uLong sourceLen));

Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer.

Maybe a=1024 isn't big enough? I think you need to call compressBound to get a suitable value.



回答3:

I tried to use the zlib from MSYS (accessible with mingw-get) and got the same problem as described below.

The solution is to do a static link instead of using the shared library. Just remove or rename the import library libz.dll.a to avoid the linker to do a link with the msys-z.dll.

Recompile and it will be working.

Another way is to install zlib yourself from the zlib.net website. Remove the one from mingw-get.



回答4:

Using zlib in your code is extremely simple, something that the documentation ( or the various answers on stackoverflow I found ) don't make obvious.

The following technique works for any compiler and IDE. I tested it in windows mingw using code:blocks, which is why I am posting it as an answer to this question.

  1. Download the zlib source code from http://www.zlib.net/

  2. Copy all the .c and .h files from the root folder of the zlib source to a folder in your compiler search path.

  3. Add the zlib source files to the IDE project.

  4. Add #include "zlib.h" to your source code

  5. Call compress or uncompress

That's it. It could hardly be simpler.

All you have to be careful about is memory management, since this is c code.

To make things even simpler for myself, I have put together a c++ wrapper which you are welcome to use, like this:

/** ZLIB C++ wrapper

Usage:

<pre>

    #include "cZLIB.h"

    {
    // compress data in bigbuffer
    raven::set::cZLIB ZLIB;
    ZLIB.Compress( bigbuffer, sizebigbuffer );

    // use compressed buffer, before ZLIB goes out of scope
    use( ZLIB.Buffer(), ZLIB.Length() );

    }

    ...

    {

    // decompress data in smallbuffer
    raven::set::cZLIB ZLIB;
    ZLIB.Inflate( smallbuffer, sizesmallbuffer )

    // use decompressed data, before ZLIB goes out of scope
    use( ZLIB.Buffer(), ZLIB.Length() );

    }

</pre>

Build:

Download this code ( cZLIB.h and cZLIB.cpp ) from

https://github.com/JamesBremner/raven-set

and install somewhere in your compiler search path.
Let's assume you install it in folder .../src.

Download the zlib source code from http://www.zlib.net/
Copy all the .c and .h files from the root folder of the zlib source
to a new folder .../src/zlib

Add the files cZLIB.h, cZLIB.cpp and all the files in .../src/zlib
to the IDE project.

Build.

 */
class cZLIB
...