Что такое __CxxFrameHandler4 и что именно означает ошибка компоновщика «неразрешенный внешний символ __CxxFrameHandler4»?

#visual-studio #visual-c #vcpkg

#visual-studio #visual-c #vcpkg

Вопрос:

Я использую несколько библиотек, созданных с помощью vcpkg (таких как civet-web и prometheus-cpp), для своих проектов на Visual C . При сборке x86 все идеально, в x64 я получаю кучу ошибок компоновщика:

ошибка LNK2001: неразрешенный внешний символ __CxxFrameHandler4

Поиск в Интернете всех ссылок на этот символ / ошибку касается конкретных проектов, я не могу найти, что такое __CxxFrameHandler4 и какую проблему выделяет эта ошибка. Я не знаю, связано ли это с тем, как vcpkg создает библиотеку, или проблема в моем проекте, или как начать искать решение.

Я нашел эту статью в блоге, но она относится к предварительному просмотру VS2019, я не могу найти никаких связанных с ней настроек: https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64 /

Если кто-нибудь может объяснить, что это такое, это было бы большой помощью.

Комментарии:

1. __CxxFrameHandler4 является частью более новой (начиная с версии 2019 16.3 ) 64-разрядной обработки исключений FH4 . Я думаю LNK2001 , это могло бы произойти, если бы вы связали модули, созданные с несовпадающими версиями компилятора / наборов инструментов.

Ответ №1:

Я столкнулся с теми же проблемами при попытке установить и использовать cpr с vcpkg. Я хотел использовать библиотеку cpr в проекте VS2015.

Причина: у меня был установлен VS2019. vcpkg использует последнюю версию набора инструментов Visual Studio.
Решение: добавьте свой собственный триплет или измените существующий таким образом, чтобы использовался указанный вами набор инструментов. Добавление в моем случае не сработало, поэтому я изменил существующие «триплетные» файлы в папке triplet в vcpkg. Я хотел, чтобы vcpkg использовал набор инструментов, который поставляется с VS2015 (это V140)

Содержимое файла x86-windows.cmake

 set(VCPKG_TARGET_ARCHITECTURE x86)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE dynamic)
set(VCPKG_PLATFORM_TOOLSET "v140")
set(VCPKG_DEP_INFO_OVERRIDE_VARS "v140")
 

Содержимое файла x64-windows.cmake

 set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE dynamic)
set(VCPKG_PLATFORM_TOOLSET "v140")
set(VCPKG_DEP_INFO_OVERRIDE_VARS "v140")
 

Комментарии:

1. На самом деле я в конце концов понял это именно так с момента публикации, мне пришлось заставить vcpkg не использовать последний набор инструментов vs2019. Вы можете продемонстрировать пример изменений триплета для всех, кто это видит

2. @Mr.Boy, добавлены последние две строки. Первые 3 строки уже были там в обоих случаях.

3. Простите мое невежество, но есть ли способ сделать это через настройки проекта? Я не вызываю cmake напрямую, но Visual Studio — это когда я создаю проект или решение. Я не вижу ни одного файла «.cmake», который я мог бы отредактировать для своего проекта.

Ответ №2:

Более общий ответ заключается в том, что это происходит, если вы смешиваете объекты, которые были созданы с помощью разных наборов инструментов платформы, например,

  • Visual C 2015 (v140)
  • Visual C 2017 (v141)

Как правило, вы (или кто-то другой), возможно, создали зависимость вашего проекта с помощью другой версии компилятора (набора инструментов платформы), и исправьте это, чтобы изменить набор инструментов платформы либо вашего проекта, либо зависимости (или используйте правильную сборку зависимости, если вы использовали предварительно созданный пакет)

Ответ №3:

Я думаю, вы указали правильную статью, которая https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64 /

Я столкнулся с аналогичной проблемой при связывании 64-разрядной библиотеки, созданной с помощью набора инструментов VC143, с 64-разрядным приложением, созданным с помощью набора инструментов VC141.

После добавления следующих свойств в проект встроенной статической библиотеки VC143 я смог создать приложение. Это отключает новую функцию, упомянутую в вышеупомянутой статье (обработка исключений меньше)

 VS2019->Properties->C/C  ->Command Line add '-d2FH4-'
VS2019->Properties->Linker->Command Line add '-d2:-FH4-'