libpng 1.616在VS2012 C++中的png_read_png上崩溃
libpng 1.616 crashing on png_read_png in VS2012 C++
我使用的是win7 64位家庭版。我的所有项目都设置为使用C++在32位环境中构建。我已经使用MDd运行时在调试模式下成功地构建了libpng。我有两个正在进行的项目。我的第一个项目是在VS2010,第二个是在VS2012。在我的计算机中,我创建了一个环境变量,设置为该库的路径,以使链接在我的项目中更容易。我的两个项目都使用MDd和多字节,这与libpng使用的相同。我的所有路径和依赖项都是正确的。我还将libpng16.dll复制到两个项目中,并将其作为构建的可执行文件复制到同一目录中。我可以成功地编译和构建这两个项目。我的VS2010项目运行并渲染加载的PNG图形,但我在VS2012中的项目没有。当我调用png_read_png抛出并在以下行中断的未处理异常时,它崩溃了:
check = fread( data, 1, length, png_voidcast( png_FILE_p, png_ptr->io_ptr ) );
在pngrio.c.中给出此错误:
First-chance exception at 0x77308E19 (ntdll.dll) in Game_debug.exe: 0xC0000005:
Access violation writing location 0x00000014.
这个问题不在我的源代码中,因为我知道它在我的VS2010项目中有效,并且我正在使用相同的实现来加载我的VS2012项目中的png。我不确定我链接到的库是否是在VS2010中构建的,或者VS2010构建的库中是否有我的VS2012项目不喜欢的一些命令行/编译器设置。我已经阅读了png文档,在网上搜索了几个小时,似乎找不到任何相关的内容。任何形式的帮助、提示、指点或建议都会对我大有裨益。
阅读libpng源代码中的projects/vstudio/readme.txt文件,特别是第41行开始的段落。
您正在向libpng传递一个(FILE*),可能使用png_init_io。Visual Studio在尝试访问底层FILE结构时在fread内部崩溃。
这是因为您使用fopen从一个Visual Studio运行时创建了FILE*,但libpng链接到不同的Visual Studio运行库(msvcrt或类似的东西);这两个运行时是不兼容的。
有很多方法可以导致这种情况发生,但如果使用zlib DLL,几乎肯定会发生。你是使用projects/vstudio来构建libpng,还是自己尝试过?如果你没有使用projects/vstudio,你就只能靠自己了;-)
1) 不要将libpng和zlib都构建到单独的DLL中;将libpng DLL链接到静态zlib(projects/vstudio就是这样做的),或者在项目中使用静态libpng(而不是DLL)(projects/vs.tudio也构建其中一个。)
2) 阅读各种Visual Studio运行时。运行的所有程序都必须使用完全相同的运行时;检查每个项目,看看它有什么运行时。最好使用默认(/MD)
3) 如果您认为在libpng中遇到了错误,请静态链接您的应用程序(即不要使用Visual Studio构建的任何DLL),然后重试。Windows DLL很好;是VisualStudio使用VisualStudio运行时破坏了一切。
4) 如果静态链接时出现问题,请确保DEBUG设置在任何地方都是相同的。您不能混合"最大DEBUG",因为MSVC运行时的调试版本(其中任何一个,甚至在Visual Studio之前)与发布版本不兼容。
事实上,最好不要使用png_init_io;libpng支持这一点。提供您自己的读写回调。可以安全地在这些(fread)中使用stdio,因为它们与fopen调用是在同一个DLL(您编写的DLL)中实现的。只要你不通过DLL边界传递(FILE*),你就应该是安全的;从来没有人解释或理解过两个DLL(zlib,libpng)的行为。
John Bowler
经过数小时的尝试和错误,在其他人的帮助下,我终于能够使用相同版本的libpng成功构建我的2012项目。我要做的是在libpng所在的目录中创建3个文件夹
- VS2010\lpng1616\,VS2010\zlib-1.2.8
- VS2012\lpng1616\,VS2012\zlib-1.2.8
- VS2013\lpng1616\,VS2013\zlib-1.2.8
在这3个文件夹中的每一个文件夹中,我都必须在受尊重的Visual Studio版本中打开libpng的解决方案。构建发布和调试。
然后在我的计算机上为环境变量创建了3个,而不是一个。
- PNG_SDK_2010设置为VS2010\lpng1616\
- PNG_SDK_2012"VS2012\lpng1616\
- PNG_SDK_2013"VS2013\lpng1616\
然后回到我的VS2010和VS2012项目中,使用环境变量设置路径,相应地用新建的库替换旧的过时库,清理了解决方案,两个项目都能正常工作!
因此,总之,如果您使用的是外部库,您可以从网络上下载该库,该库附带了一个解决方案,您需要打开该解决方案并自行构建以进行链接,并且跨不同版本的Visual Studio的项目需要该库,则您必须在您计划的同一版本的Visual Studio中打开该库附带的解决方案与当前项目一起使用。我希望我自己的处境能成为别人的答案!
刚刚在libpng和curl方面遇到了同样的问题lib和curl都使用"msvcrt.dll"所以我只是添加了讨厌的变通方法
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");
}
这对我很有效。闻起来很臭,但不管
Slso的优点是它适用于调试和发布版本
- 在CToolBar对象中使用PNG时出现问题
- 使用 ImageIO.read() 生成的图像是否仍然使用传递给它的相同内存?
- 从存储为 Windows 资源 (c++) 的 png 中获取 png 文件数据
- std::ifstream::read 不会读取所有 512 字节,并设置 EOF 和失败位
- 使用 stbi_write_png,如何将 0 和 1 的矩形字节数组转换为单色 png 文件?
- write() 和 read() 中几乎没有混淆
- C++ TCP 套接字通信 - 连接按预期工作,几秒钟后失败,没有收到新数据,read() 和 recv() 块
- 为什么调试器引发"read access violation. this was nullptr"异常?
- 对同一文件使用 .read 的次数是否有限制?
- Win32 API - HWND "{unused = ???} Unable to read memory"错误
- 为什么我会"Invalid read of size 8"?(瓦尔格林德)
- QDataStream read to QVector
- 将 FFMPEG 帧写入 png/jpeg 文件
- asio::read() 需要很长时间,使用 asio::write 没有问题
- Read OpenCV Mat 16bit to QImage 8bit Greyscale
- 如果 I/O read() 处于阻塞阶段,如何使用 Ctrl+C 退出 C++ 程序?
- 将位图 (bmp) 转换为具有透明度的 png (Windows c++)
- 如何将 (serverClients[i].read() 传递给 ESP8266 上的字节数组
- 将 Lora.read() 转储到数组
- 如何启用libMagick++以保存.png文件格式