1

我是win7 64位家庭版。我的所有项目都设置为使用 C++ 在 32 位环境中构建。我已经使用 MDd 运行时在调试模式下成功构建了 libpng。我有两个活跃的项目。我的第一个项目是在 VS2010 中,我的第二个项目是在 VS2012 中。在我的计算机中,我创建了一个设置为该库路径的环境变量,以使我的项目中的链接更容易。我的两个项目都使用 MDd 以及 libpng 使用的多字节。我所有的路径和依赖项都是正确的。我还将 libpng16.dll 复制到与它们构建的可执行文件相同的目录中的两个项目中。我可以成功编译和构建这两个项目。我的 VS2010 项目运行并渲染加载的 PNG 图形,但是我在 VS2012 中的项目没有。

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 中构建的,还是我的 VS2012 项目不喜欢的 VS2010 构建库中有一些命令行/编译器设置是否会有所不同。我已经阅读了 png 文档并在网上搜索了几个小时,但似乎找不到任何相关的东西。任何形式的帮助、提示、指示或建议都会对我有很大帮助。

4

3 回答 3

4

阅读 libpng 源代码中的文件 projects/vstudio/readme.txt,特别是从第 41 行开始的段落。

您正在将 (FILE*) 传递给 libpng,可能使用 png_init_io。Visual Studio 在尝试访问底层 FILE 结构时在 fread 内部崩溃。

这是因为您使用 fopen 从一个 Visual Studio 运行时创建了 FILE*,但 libpng 链接到不同的 Visual Studio 运行时(msvcrt 或类似的东西);这两个运行时不兼容。

有很多方法可以导致这种情况发生,但如果您使用 zlib DLL,它几乎肯定会发生。您是使用项目/vstudio 构建 libpng 还是尝试自己构建?如果您没有使用项目/vstudio,那么您是一个人;-)

1) 不要将 libpng 和 zlib 都构建到单独的 DLL 中;将 libpng DLL 链接到静态 zlib(这是项目/vstudio 所做的)或在项目中使用静态 libpng(不是 DLL)(项目/vstudio 也构建其中之一。)

2) 阅读各种 Visual Studio 运行时。您运行的所有内容都必须使用完全相同的运行时;检查每个项目以查看它具有的运行时。最好使用默认值 (/MD)

3) 如果您认为在 libpng 中遇到错误,请静态链接您的应用程序(即不要使用 Visual Studio 构建的任何 DLL),然后重试。Windows DLL 很好;破坏一切的是使用 Visual Studio 运行时的 Visual Studio。

4) 如果在静态链接时出现问题,请确保您的 DEBUG 设置在所有地方都相同。您不能混合使用'n'max DEBUG,因为 MSVC 运行时的调试版本(其中任何一个,甚至是 Visual Studio 之前的版本)与发布版本不兼容。

实际上最好不要使用 png_init_io;libpng 支持这一点。提供您自己的读写回调。您可以安全地在这些 (fread) 中使用 stdio,因为它们在与调用 fopen 相同的 DLL(您编写的那个)中实现。只要您不通过 DLL 边界传递 (FILE*) 您应该是安全的,也许;没有人解释或理解这两个 DLL(zlib、libpng)的行为。

约翰·鲍勒

于 2015-03-23T15:23:29.817 回答
2

经过数小时的反复试验,并在其他人的一点点帮助下,我终于能够使用相同版本的 libpng 成功构建我的 2012 项目。我必须做的是在 libpng 所在的目录中,我必须创建 3 个文件夹

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

在这 3 个文件夹中的每一个中,我都必须在受尊敬的 Visual Studio 版本中打开 libpng 的解决方案。构建发布和调试。

然后在我的计算机上为环境变量创建不是 1 而是 3。

  1. PNG_SDK_2010 设置为 VS2010\lpng1616\
  2. PNG_SDK_2012 "VS2012\lpng1616\
  3. PNG_SDK_2013 "VS2013\lpng1616\

然后回到我的 VS2010 和 VS2012 项目,使用环境变量设置路径,相应地用新构建的库替换旧的陈旧库,清理解决方案,两个项目都能正常工作!

因此,总而言之,如果您使用可以从网络下载的外部库,该库附带您需要打开并构建自己以链接的解决方案,并且您需要为跨不同版本 Visual Studio 的项目使用相同的库,那么您将必须在您计划与当前项目一起使用的同一版本的 Visual Studio 中打开该库附带的解决方案。我希望我自己的情况能够作为其他人的答案!

于 2015-03-23T18:21:03.110 回答
1

刚刚遇到了与 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,优点是它适用于调试和发布版本

于 2016-09-11T12:39:32.837 回答