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 行开始的段落。
您正在将 (FILE*) 传递给 libpng,可能使用 png_init_io。 Visual Studio 当它试图访问底层 FILE 结构时在 fread 内部崩溃。
这是因为您从一个 Visual Studio 运行 时间使用 fopen 创建了 FILE*,但是 libpng 是 link 针对不同的 Visual Studio 运行 编辑的时间(msvcrt 或类似的东西);这两个 运行 时间不兼容。
有很多方法可以导致这种情况发生,但如果您使用 zlib DLL,几乎肯定会发生这种情况。您是使用 projects/vstudio 构建 libpng 还是尝试自己构建?如果您没有使用 projects/vstudio,您只能靠自己了 ;-)
1) 不要将 libpng 和 zlib 都构建到单独的 DLL 中; link 针对静态 zlib 的 libpng DLL(这是 projects/vstudio 所做的)或在您的项目中使用静态 libpng(不是 DLL)(projects/vstudio 也构建其中之一。)
2) 阅读各种 Visual Studio 运行 次。您 运行 必须使用完全相同的 运行 时间;检查每个项目,看看它有多少 运行时间。最好使用默认值 (/MD)
3) 如果您认为您在 libpng link 静态应用程序中遇到了错误(即不要使用 Visual Studio 构建的任何 DLL)并重试。 Windows DLL 没问题;正是 Visual Studio 那些使用 Visual Studio 运行 时间的人打破了一切。
4) 如果在您 link 静态时出现问题,请确保您的 DEBUG 设置在所有地方都相同。您不能混合 'n'max DEBUG,因为 MSVC 的调试版本 运行 次(其中任何一个,甚至是 Visual Studio 之前的版本)与发行版本不兼容。
其实最好不要用png_init_io; libpng 支持这个。提供您自己的读写回调。您 可以 在这些 (fread) 中安全地使用 stdio,因为它们是在与调用 fopen 相同的 DLL(您编写的 DLL)中实现的。只要您不通过 DLL 边界传递 (FILE*),您就应该是安全的,也许吧;没有人解释或理解这两个 DLL(zlib、libpng)的行为。
约翰·鲍勒
经过数小时的尝试和错误,并在其他人的一点点帮助下,我终于能够使用相同版本的 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 项目使用环境变量设置路径相应地用新构建的库替换旧的陈旧库,清理解决方案并且两个项目都正常工作!
所以总而言之,如果您使用的是外部库,您可以从网上下载这些库,其中包含一个解决方案,您需要打开并自己构建以 link 反对,并且您需要这个相同的库来进行项目在不同版本的 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");
}
它对我有用。
味道不好,不过没关系
此外,优点是它对调试和发布版本都适用
我是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 行开始的段落。
您正在将 (FILE*) 传递给 libpng,可能使用 png_init_io。 Visual Studio 当它试图访问底层 FILE 结构时在 fread 内部崩溃。
这是因为您从一个 Visual Studio 运行 时间使用 fopen 创建了 FILE*,但是 libpng 是 link 针对不同的 Visual Studio 运行 编辑的时间(msvcrt 或类似的东西);这两个 运行 时间不兼容。
有很多方法可以导致这种情况发生,但如果您使用 zlib DLL,几乎肯定会发生这种情况。您是使用 projects/vstudio 构建 libpng 还是尝试自己构建?如果您没有使用 projects/vstudio,您只能靠自己了 ;-)
1) 不要将 libpng 和 zlib 都构建到单独的 DLL 中; link 针对静态 zlib 的 libpng DLL(这是 projects/vstudio 所做的)或在您的项目中使用静态 libpng(不是 DLL)(projects/vstudio 也构建其中之一。)
2) 阅读各种 Visual Studio 运行 次。您 运行 必须使用完全相同的 运行 时间;检查每个项目,看看它有多少 运行时间。最好使用默认值 (/MD)
3) 如果您认为您在 libpng link 静态应用程序中遇到了错误(即不要使用 Visual Studio 构建的任何 DLL)并重试。 Windows DLL 没问题;正是 Visual Studio 那些使用 Visual Studio 运行 时间的人打破了一切。
4) 如果在您 link 静态时出现问题,请确保您的 DEBUG 设置在所有地方都相同。您不能混合 'n'max DEBUG,因为 MSVC 的调试版本 运行 次(其中任何一个,甚至是 Visual Studio 之前的版本)与发行版本不兼容。
其实最好不要用png_init_io; libpng 支持这个。提供您自己的读写回调。您 可以 在这些 (fread) 中安全地使用 stdio,因为它们是在与调用 fopen 相同的 DLL(您编写的 DLL)中实现的。只要您不通过 DLL 边界传递 (FILE*),您就应该是安全的,也许吧;没有人解释或理解这两个 DLL(zlib、libpng)的行为。
约翰·鲍勒
经过数小时的尝试和错误,并在其他人的一点点帮助下,我终于能够使用相同版本的 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 项目使用环境变量设置路径相应地用新构建的库替换旧的陈旧库,清理解决方案并且两个项目都正常工作!
所以总而言之,如果您使用的是外部库,您可以从网上下载这些库,其中包含一个解决方案,您需要打开并自己构建以 link 反对,并且您需要这个相同的库来进行项目在不同版本的 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");
}
它对我有用。 味道不好,不过没关系
此外,优点是它对调试和发布版本都适用