Сбой libpng 1.616 на png_read_png в VS2012 C++

Я на Win7 64bit Home Edition. Все мои проекты собираются для сборки в 32-битной среде с использованием C++. Я успешно построил libpng в режиме отладки, используя среду выполнения MDd. У меня есть два активных проекта. Мой первый проект в VS2010, а мой второй в VS2012. На своем компьютере я создал переменную среды, в которой указан путь к этой библиотеке, чтобы упростить компоновку в моих проектах. Оба моих проекта используют MDd, а также многобайтовые, то же самое, что и libpng. Все мои пути и зависимости верны. Я также скопировал файл libpng16.dll в оба проекта в том же каталоге, что и их встроенный исполняемый файл. Я могу успешно скомпилировать и построить оба проекта. Мой проект VS2010 запускается и отображает загруженную графику PNG, однако мой проект в VS2012 - нет. Это происходит сбой, когда я вызываю png_read_png throwing и необработанное исключение, которое разрывается в этой строке:

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, и я использую ту же реализацию для загрузки png в моем проекте VS2012. Я не уверен, если из-за этого будет иметь значение, что библиотека, на которую я ссылаюсь, была построена в VS2010 или есть какие-то настройки командной строки / компилятора во встроенной библиотеке VS2010, которые не нравятся моему проекту VS2012. Я прочитал png документацию и часами искал в Интернете, но не нашел ничего подходящего. Любая помощь, советы, указатели или предложения могут мне помочь.

3 ответа

Решение

После долгих часов проб и ошибок и небольшой помощи от других я наконец смог успешно построить свой проект 2012 года, используя ту же версию libpng. То, что я должен был сделать, было в моих каталогах, где находится 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

И в каждой из этих трех папок мне приходилось открывать решение libpng в уважаемых версиях Visual Studio. Создайте как релиз, так и отладки.

Затем на моем компьютере для переменных среды мне пришлось создать не одну, а 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, которую вы планируете использовать с текущим проектом. Я надеюсь, что моя собственная ситуация станет ответом для других!

Прочитайте файл projects/vstudio/readme.txt в исходном коде libpng, в частности, абзац, начинающийся со строки 41.

Вы передаете (FILE*) в libpng, вероятно, используя png_init_io. Visual Studio аварийно завершает работу внутри fread при попытке доступа к базовой структуре FILE.

Это потому, что вы создали FILE *, используя fopen из одной среды выполнения Visual Studio, но libpng связан с другой средой выполнения Visual Studio (msvcrt или что-то в этом роде); два времени выполнения несовместимы.

Есть много способов вызвать это, но это почти наверняка произойдет, если вы используете zlib DLL. Вы используете проекты / vstudio для сборки libpng или вы пытались сделать это самостоятельно? Если вы не использовали проекты / vstudio, вы сами по себе;-)

1) Не встраивайте libpng и zlib в отдельные библиотеки DLL; связать libpng DLL со статическим zlib (это то, что делает projects / vstudio) или использовать статический libpng (не DLL) в вашем проекте (projects/vstudio также создает один из них).

2) Ознакомьтесь с различными средами выполнения Visual Studio. Все, что вы запускаете, должно использовать одно и то же время выполнения; проверьте каждый проект, чтобы увидеть, какое время он имеет. Желательно использовать по умолчанию (/ MD)

3) Если вы считаете, что столкнулись с ошибкой в ​​libpng, статически связывайте ваше приложение (т.е. не используйте библиотеки DLL, созданные Visual Studio) и повторите попытку. Windows DLL в порядке; это Visual Studio, которые используют среду выполнения Visual Studio, которые ломают все.

4) Если проблема возникает при статической ссылке, убедитесь, что настройки DEBUG везде одинаковы. Вы не можете смешивать и отключать DEBUG, потому что отладочная версия сред выполнения MSVC (любая из них, даже до Visual Studio) не совместима с версиями выпуска.

На самом деле лучше не использовать png_init_io; libpng поддерживает это. Предоставьте свои собственные обратные вызовы для чтения и записи. Вы можете безопасно использовать stdio в этих (fread), потому что они реализованы в той же DLL (той, что вы пишете), что и вызовы fopen. Пока вы не пропустите (FILE*) через границу DLL, возможно, вы должны быть в безопасности; никто никогда не объяснял и не понимал поведение двух DLL (zlib, libpng).

Джон Боулер

Просто столкнулся с одной и той же проблемой с 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, преимущество в том, что он хорошо работает как для отладочной, так и для релизной версии

Другие вопросы по тегам