libpng 1.616 crashing on png_read_png in VS2012 C++

1

I am on win7 64bit home edition. All of my projects are set to build in a 32bit environment using C++. I have successfully built libpng in debug mode using MDd runtime. I have two active projects. My first project is in VS2010 and my second is in VS2012. Within my computer I created an environment variable set to the path for this library to make linking easier in my projects. Both my projects are using MDd as well as multibyte which is the same that libpng uses. All of my paths and dependencies are correct. I also copied over the libpng16.dll into both projects within the same directory as their built executable. I can successfully compile and build both projects. My VS2010 project runs and renders the loaded PNG graphic, however my project in VS2012 doesn't. It crashes when I call png_read_png throwing and unhandled exception that breaks on this line:

check = fread( data, 1, length, png_voidcast( png_FILE_p, png_ptr->io_ptr ) );

within pngrio.c. giving this error:

First-chance exception at 0x77308E19 (ntdll.dll) in Game_debug.exe: 0xC0000005: 
Access violation writing location 0x00000014.

The problem is not within my source code since I know that it works in my VS2010 project and I am using the same implementation to load the png in my VS2012 project. I am not sure off hand if it makes a difference that the library I am linking to was built in VS2010 or if there are some command line / compiler settings within the VS2010 built library that my VS2012 project doesn't like. I've read through the png documentation and searched online for hours and couldn't seem to find anything relevant. Any kind of help, tips, pointers or suggestions would do me a great deal.

c++
visual-studio-2012
access-violation
libpng
first-chance-exception
asked on Stack Overflow Mar 23, 2015 by Francis Cugler

3 Answers

4

Read the file projects/vstudio/readme.txt in the libpng source code, in particular the paragraph starting at line 41.

You are passing a (FILE*) to libpng, probably using png_init_io. Visual Studio crashes inside fread when it tries to access the underlying FILE structure.

This is because you created the FILE* using fopen from one Visual Studio runtime but libpng is linked against a different Visual Studio runtime (msvcrt or something like that); the two runtimes are incompatible.

There are quite a number of ways to cause this to happen but it will almost certainly happen if you use a zlib DLL. Are you using projects/vstudio to build libpng or did you try to do it yourself? If you didn't use projects/vstudio you are on your own ;-)

1) Don't build both libpng and zlib into separate DLLs; link a libpng DLL against a static zlib (this is what projects/vstudio does) or use a static libpng (not a DLL) in your project (projects/vstudio also builds one of these.)

2) Read up on the various Visual Studio runtimes. Everything that you run must use exactly the same runtime; check every project to see what runtime it has. Preferably use the default (/MD)

3) If you think you have encountered a bug in libpng link your application statically (i.e. don't use any DLLs built by Visual Studio) and try again. Windows DLLs are fine; it's the Visual Studio ones that use the Visual Studio runtime that break everything.

4) If the problem happens when you link statically make sure your DEBUG settings are the same everywhere. You can't mix'n'max DEBUG because the debug version of the MSVC runtimes (any of them, even pre-Visual Studio) are not compatible with the release versions.

In fact it is better not to use png_init_io; libpng supports this. Provide your own read and write callbacks. You can use stdio in those (fread) safely because they are implemented in the same DLL (the one you write) as calls fopen. So long as you don't pass a (FILE*) across a DLL boundary you should be safe, maybe; no one has ever explained or understood the two DLL (zlib, libpng) behavior.

John Bowler

answered on Stack Overflow Mar 23, 2015 by John Bowler
2

After considerable hours of trial and errors, and with the little bit of help from others I was finally able to successfully build my 2012 project using the same version of libpng. What I had to do was in my directories where the libpng is located I had to create 3 Folders

  1. VS2010\lpng1616\ , VS2010\zlib-1.2.8
  2. VS2012\lpng1616\ , VS2012\zlib-1.2.8
  3. VS2013\lpng1616\ , VS2013\zlib-1.2.8

And within each of these 3 folders I had to open libpng' solution within the respected versions of Visual Studio. Build out both release and debugs.

Then on my computer for the environment variables, I had to create not one but 3.

  1. PNG_SDK_2010 set to VS2010\lpng1616\
  2. PNG_SDK_2012 " VS2012\lpng1616\
  3. PNG_SDK_2013 " VS2013\lpng1616\

Then go back into my VS2010 and VS2012 projects set the paths using the environment variables accordingly replace the old stale libraries with the newly built ones, did a clean of the solution and both projects work properly!

So in conclusion if you are using outside libraries that you can download from the net that comes with a solution that you need to open and build out yourself to link against and you need this same library for projects across different versions of Visual Studio then you will have to open the solution that came with that library within the same version of Visual Studio that you are planning on using with your current project. I hope that my own situation comes to serve as an answer for others!

answered on Stack Overflow Mar 23, 2015 by Francis Cugler
1

Just faced the same issue with libpng and curl Both lib and curl use "msvcrt.dll" So I just added nasty workaround

HMODULE h = LoadLibraryA("msvcrt.dll");
typedef FILE * (*FP)(char *f, char *m);
FP myf = (FP)GetProcAddress(h, "fopen");
if (myf)
{
    fp = myf((char *)lpszFileName, "wb");
}

and it worked for me. Smells bad, but no matter

Slso, the advantage is that it works well for both debug and release version

answered on Stack Overflow Sep 11, 2016 by oleg3d

User contributions licensed under CC BY-SA 3.0