Ошибка компоновщика при попытке использовать ImageMagick в качестве статической библиотеки с компилятором Visual Studio

Этот вопрос уже задавался здесь, но, поскольку у меня есть еще много подробностей, я думаю, что лучше начать с нового вопроса.

У меня проблемы с подключением файлов ImageMagick lib в моей программе, использующей компилятор Visual Studio MSVC 2015. Вот шаги, которые я выполнил:

  • Я скомпилировал статические среды выполнения MT с помощью утилиты configure.exe и встроил в Visual Studio решение, сгенерированное им, "VisualStaticMT.sln". Это создает файлы lib, такие как "CORE_RL_Magick++_. Lib" в C:\ImageMagick-6.9.3-2\VisualMagick\lib.

  • В моей программе на C++11 конфигурация, относящаяся к ImageMagick, (я использую QtCreator, но с компилятором MSVC2015):

    INCLUDEPATH += \
        C:\ImageMagick-6.9.3-2\ImageMagick\Magick++\lib \
        C:\ImageMagick-6.9.3-2\ImageMagick
    LIBS += \
        -lC:\ImageMagick-6.9.3-2\VisualMagick\lib\CORE_RL_Magick++_ \
        -lC:\ImageMagick-6.9.3-2\VisualMagick\lib\CORE_RL_wand_ \
        -lC:\ImageMagick-6.9.3-2\VisualMagick\lib\CORE_RL_magick_
    QMAKE_CXXFLAGS += \
        -DMAGICKCORE_HDRI_ENABLE=0 \
        -DMAGICKCORE_QUANTUM_DEPTH=16
    

Часть программы содержит:

#include <Magick++.h>
...
Magick::Image img;
img = Magick::Image(filename);

При компиляции я получаю ошибки ссылки:

movie.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall Magick::Image::Image(void)" (__imp_??0Image@Magick@@QAE@XZ) referenced in function "public: __thiscall Frame<unsigned char>::Frame<unsigned char>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0?$Frame@E@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)

movie.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall Magick::Image::Image(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (__imp_??0Image@Magick@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: __thiscall Frame<unsigned char>::Frame<unsigned char>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0?$Frame@E@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)

movie.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall Magick::Image::~Image(void)" (__imp_??1Image@Magick@@UAE@XZ) referenced in function "public: __thiscall Frame<unsigned char>::Frame<unsigned char>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0?$Frame@E@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)

movie.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class Magick::Image & __thiscall Magick::Image::operator=(class Magick::Image const &)" (__imp_??4Image@Magick@@QAEAAV01@ABV01@@Z) referenced in function "public: __thiscall Frame<unsigned char>::Frame<unsigned char>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0?$Frame@E@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)

movie.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall Magick::Image::write(long,long,unsigned int,unsigned int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,enum MagickCore::StorageType,void *)" (__imp_?write@Image@Magick@@QAEXJJIIABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@W4StorageType@MagickCore@@PAX@Z) referenced in function "public: __thiscall Frame<unsigned char>::Frame<unsigned char>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0?$Frame@E@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)

movie.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: struct MagickCore::_Image const * __thiscall Magick::Image::constImage(void)const " (__imp_?constImage@Image@Magick@@QBEPBU_Image@MagickCore@@XZ) referenced in function "public: __thiscall Frame<unsigned char>::Frame<unsigned char>(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0?$Frame@E@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
release\corr.exe : fatal error LNK1120: 6 unresolved externals

Ошибка "dllimport" удивляет меня, так как я думаю, что не должно быть никакой DLL, связанной с "статическим временем выполнения MT", которое я использую.

Есть идеи, как мне решить проблему?

Благодарю.


РЕДАКТИРОВАТЬ

Еще несколько вещей, которые я попробовал:

  • Связывание библиотек со строками ниже в main.cpp привело к тем же ошибкам:

    #pragma comment(lib, "CORE_RL_Magick++_.lib")
    #pragma comment(lib, "CORE_RL_wand_.lib")
    #pragma comment(lib, "CORE_RL_magick_.lib")
    
  • Я попытался добавить все 27 файлов lib, расположенных в C:\ImageMagick-6.9.3-2\VisualMagick\lib. Если я исключаю CORE_RL_exr_.lib, я получаю ту же ошибку. Если я включу его, я получу дополнительные ошибки, которые указывают, что этот файл не должен быть добавлен:

    CORE_RL_exr_.lib(IexBaseExc.obj):-1: error: LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease' in main.obj
    

2 ответа

Ответ на связывание статических библиотек ImageMagick - убедиться, что вы также связываете все зависимые статические библиотеки!

После того, как вы скомпилировали решение для статических библиотек ImageMagick, перейдите в папку "VisualMagick" (в клонированном репозитории ImageMagick), а затем в папку "lib", где вы увидите все *_DB_*.lib а также *_RL_*.lib файлы для отладки и выпуска.

Вам необходимо включить эти имена в раздел "Дополнительные зависимости" как для выпуска, так и для отладки.

Другой ключевой аспект - обеспечение того, чтобы библиотеки были созданы тем же компилятором для той же архитектуры платформы, что и ваше собственное приложение.. (WIN32 или x64).

Возможно, вам не хватает некоторых библиотечных файлов. потому что ваша программа не может связать файл библиотеки, поэтому выдает ошибку компоновщика. Попробуйте связать файл lib извне... попробуйте этот код перед основным методом.. #pragma comment(lib, "CORE_DB_magick++. Lib")

Вы можете скачать этот lib файл по приведенной ниже ссылке.

https://github.com/moravianlibrary/Open-DPI-Detector/tree/master/OpenDpiDetector/Libraries/ImageMagick-6.7.6/VisualMagick/lib

Чтобы связать ваше приложение со статической сборкой ImageMagick, вы должны сделать несколько трюков (как для ImageMagick-7.0.8-11):

  • добавить определение препроцессора STATIC_MAGICK в ваш проект визуальной студии
  • добавить отсутствующую библиотеку ввода CORE_DB_croco_.lib/CORE_RL_croco_.lib в Linker->Input (другие библиотеки ImageMagick добавляются автоматически через #pragma)
  • переименуйте CORE_XX_liblzma_.pdb -> CORE_XX_lzma_.lib (ImageMagick связывает эту библиотеку с другим именем, возможно, ошибкой), XX = RL или DB
Другие вопросы по тегам