Exceptions when linking release libpng (1.6.38) against debug application build in MSVC 2019
When I link the release version of libpng to debug build of my application and try to write a file - I get runtime heap-related asserts and exceptions.
It only happens after the png_write_info() call. If if comment it - I get a malformed file, but no runtime errors. When I fclose() - I get "Debug assertion failed: _CrtIsValidHeapPointer(block)" And if I comment fclose() - I get an exception when application calls fcloseall() on completion.
Linking debug against debug or release against release works fine.
I think you should read Allocating and freeing memory across module boundaries, and note that even if both modules are using the same CRT DLL, debug builds will end up calling different heap functions.
https://docs.microsoft.com/en-us/cpp/c-runtime-library/potential-errors-passing-crt-objects-across-dll-boundaries may also be relevant, especially since you also mention fclose().
However, I'm a bit puzzled as the libz/libpng APIs were designed with this kind of issue in mind ... oh wait, are you using the png_image_write_to_stdio() function? That'll totally cause such issues.
P.S. Looking at the README in https://github.com/glennrp/libpng/tree/libpng16/projects/vstudio, it seems that debug builds aren't particularly well-supported.
TL;DR: don't try to mix-and-match Release and Debug builds unless you know what you're doing.
oh wait, are you using the
png_image_write_to_stdio()function? That'll totally cause such issues.
Not explicitly. But I do use png_init_io(pPngStruct, a_pFile);
So, it's using FILE * across runtimes that's causing the problem?
Not explicitly. But I do use
png_init_io(pPngStruct, a_pFile);So, it's using FILE * across runtimes that's causing the problem?
IRC that's a crasher; msvcrt.dll and msvcrtd.dll (or whatever they are called) have very different FILE structures. You need to implement your own memory and IO callbacks so that the same runtime DLL is used to create, destroy and, in the case of files reads/write the memory and file.
You also need to implement your own longjmp callback, or an error handler to avoid longjmp.
Or you could just build everything for release; that's what I always did, I don't see the point of special debug builds.