Thread: My zlib1.dll wrapper no does not work in .net 4.0

  1. #1
    Registered User
    Join Date
    Mar 2009
    Location
    england
    Posts
    209

    My zlib1.dll wrapper no does not work in .net 4.0

    Hi there. Yes, there are zlib librarys written in pure .net but I prefer to use the unmanaged zlib1.dll library as it seems to lack some of the memory leaks evident in .net versions.

    Anyway, a long time ago I made a wrapper to use it in my c# apps:

    Code:
        public class Zip
        {
            [DllImport("zlib1.dll")]
            static extern int compress(byte[] destBuffer, ref uint destLen, byte[] sourceBuffer, uint sourceLen);
    
            [DllImport("zlib1.dll")]
            static extern int uncompress(byte[] destBuffer, ref uint destLen, byte[] sourceBuffer, uint sourceLen);
    
    
            public static byte[] Compress(byte[] data)
            {
                uint _dLen = (uint)((data.Length * 1.1) + 12);
                byte[] _d = new byte[_dLen];
                compress(_d, ref _dLen, data, (uint)data.Length);
                byte[] result = new byte[_dLen];
                Array.Copy(_d, 0, result, 0, result.Length);
                return result;
            }
    
            public static byte[] Decompress(byte[] data)
            {
                uint _dLen = 8192;
                byte[] _d = new byte[_dLen];
    
                if (uncompress(_d, ref _dLen, data, (uint)data.Length) != 0)
                    return null;
    
                byte[] result = new byte[_dLen];
                Array.Copy(_d, 0, result, 0, result.Length);
                return result;
            }
    This works perfectly fine in .net versions 2, 3 and 3.5. Unfortunately it is throwing an exception in VS2010 if I have selected 4.0 (or 4.0 CP):

    Code:
    A call to PInvoke function 'WindowsFormsApplication1!WindowsFormsApplication1.Zip::compress' has unbalanced the stack.
    This is likely because the managed PInvoke signature does not match the unmanaged target signature.
    Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
    Any thoughts?

  2. #2
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Can you post the unmanaged signatures?

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I would recommend writing a C++/CLI wrapper for this object and ditch the pInvoke's. It will save you a lot of headaches and it's more natural to use the object from C#.

  4. #4
    Registered User
    Join Date
    Mar 2009
    Location
    england
    Posts
    209
    Hi again. Thank you all for your feed back so far. Here's the compress sig...

    Code:
    int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
    ...uncompress is the same as above.

    After some general reading on this exception, via google, it's become apparent that a lot of people are suffering similar problems in .net 4.0, even with some suprisingly well know functions such as SetWindowLong and so on.

    What is apparent also, is that running your program from outside of VS2010, the exception is not thrown. It only occurs when running in debug mode within the VS ide. This is also true in my case.

    Microsoft have a solution (can we call it that?), which is to go in your project properties, and uncheck the "pinvokestackimbalance" checkbox, located in debug->exceptions->managed debugging assistants.

    This has worked for me, which I am pleased about, and am willing to call this thread solved, however it seems very unusual that a wrapper which worked for so many years for me, across numerous updates of .net should suddenly no longer be considered valid.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    It seems to be a calling convention problem. zlib uses cdecl calling convention, and the default in .NET is to assume stdcall.

    This would give the stack issue because in stdcall, the callee would have to clean the stack (so the CLR expects the DLL to clean the stack) while in cdecl the caller cleans the stack (so the DLL expects the CLR to clean the stack). The end result is that the stack doesn't get cleaned by either, so each call effectively consumes a little bit of stack space that is never given back.

    Try changing to this:

    [DllImport("zlib1.dll", CallingConvention=CallingConvention.Cdecl) ]
    Last edited by Cat; 05-12-2010 at 03:15 AM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  6. #6
    Registered User
    Join Date
    Mar 2009
    Location
    england
    Posts
    209
    Cat, that worked a treat! Thank you.

  7. #7
    Registered User
    Join Date
    Apr 2011
    Posts
    2
    How Can I implement this code to compress and uncompress files?

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You could start your own thread, with some meaningful information (or an attempt).

    Rather than hijacking an old thread with not much more than "hey, me too".
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM
  2. .NET; What is your opinion?
    By CompiledMonkey in forum A Brief History of Cprogramming.com
    Replies: 33
    Last Post: 05-07-2002, 12:49 AM
  3. Your opinion about .NET
    By Shiro in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 04-05-2002, 02:55 PM
  4. .net
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 02-15-2002, 01:15 AM
  5. Visual J#
    By mfc2themax in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 10-08-2001, 02:41 PM