Сбой 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 папки
- VS2010 \ lpng1616 \, VS2010 \ zlib-1.2.8
- VS2012 \ lpng1616 \, VS2012 \ zlib-1.2.8
- VS2013 \ lpng1616 \, VS2013 \ zlib-1.2.8
И в каждой из этих трех папок мне приходилось открывать решение libpng в уважаемых версиях Visual Studio. Создайте как релиз, так и отладки.
Затем на моем компьютере для переменных среды мне пришлось создать не одну, а 3.
- PNG_SDK_2010 установлен на VS2010 \ lpng1616 \
- PNG_SDK_2012 "VS2012 \ lpng1616 \
- 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, преимущество в том, что он хорошо работает как для отладочной, так и для релизной версии