Меню Закрыть

Lnk2019 ссылка на неразрешенный внешний символ main

Я не знаю, что с ним не так.. Я не могу найти, где ошибка, комментируя реализацию, также не разрешает ошибку.

Файл заголовка

Источник

Даже если ваш проект имеет метод main() , компоновщик иногда путается. Вы можете решить эту проблему в Visual Studio 2010, выбрав

Проект → Свойства → Свойства конфигурации → Коннектор → Система

и сменив SubSystem на Консоль.

У нас также была эта проблема. Мой коллега нашел решение. Это оказалось переопределение "основного" в заголовке третьей стороны:

Итак, решение заключалось в том, чтобы добавить:

перед нашей основной функцией.

Это явно глупость!

Если у вас есть функция _tmain в ваших проектах, вам нужно include .

Вам нужна функция main() , поэтому программа знает, с чего начать.

Если кто-то пропустил очевидное; обратите внимание: если вы создадите приложение GUI и " -subsystem: windows" в link-args, запись приложения WinMain @16 . Не main(). Следовательно, вы можете использовать этот фрагмент для вызова основного():

Вы реализовали функцию main() ?

[править]

У вас есть main() в другом исходном файле, поэтому вы, вероятно, забыли добавить его в свой проект.

Чтобы добавить существующий исходный файл: в Обозреватель решений щелкните правой кнопкой мыши папку Исходные файлы, выберите Добавить, а затем нажмите Существующий элемент. Теперь выберите исходный файл, содержащий main()

У меня была эта проблема, несмотря на:

  • с main() ; и
  • настройка всех других проектов в моем решении как статических библиотек.

Мое возможное исправление было следующим:

  • my main() был в пространстве имен, поэтому был эффективно назван something::main() . удаление этого пространства имен устраняло проблему.

Если вы используете Visual Studio. Причина, по которой вы можете получить эту ошибку, может быть связана с тем, что вы изначально создали новый файл header.h и затем переименовали его в файл file.cpp, где вы поместили функцию main().

Чтобы исправить проблему, щелкните правой кнопкой мыши файл file.cpp → щелкните Свойства перейдите на страницу Свойства конфигурации → Общие → Тип элемента и измените его значение на C/С++ вместо заголовка C/С++.

Я столкнулся с ошибкой LNK2019 при работе над проектом DLL в Visual Studio 2013.

Я добавил новую конфигурацию в проект. Но вместо того, чтобы иметь "Тип конфигурации" как "Динамическая библиотека", визуальная студия добавила его как "Приложение". Это привело к ошибке LNK2019.

Исправлена ​​ошибка LNK2019, перейдя в Project → Properties → Configuration Properties → General и изменив "Тип конфигурации" на "Dynamic Library (.dll)" и "Target Extension" на ".dll".

Да, исходный вопрос говорит о проекте консоли/приложения, что является другой проблемой, чем мой ответ. Но я считаю, что добавление этого ответа может помочь кому-то (как и мне), который наткнулся на эту тему.

Самая актуальная документация по Visual Studio 2017: Документация по Visual Studio 2017.

неразрешенный внешний символ "symbol", на который существует ссылка в функции "function"

Компоновщику не удалось найти определение внешнего символа " symbol ", используемого в функции " function ".

Существует множество проблем, которые могут вызвать эту ошибку. В данном разделе содержатся сведения, которые помогут определить причину возникновения ошибки и найти решение проблемы.

Объект символ имя, компилятор использует для функций или глобальных переменных. Внешний символ имя, используемое для ссылки на символ, который определен в другом файле источника или объекта. Компоновщик должен устранить, или определение для внешнего символа для каждой функции или глобальной переменной, используемых каждой скомпилированный файл когда связана с приложением или DLL. Если компоновщику не удается найти соответствующее определение для внешнего символа ни в одном связанном файле, он генерирует ошибку LNK2019.

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

Код, использующий компоновку C++ использует Декорирование имен, также известный как декорированием имен, для кодирования дополнительных сведений о типе и соглашение о вызовах в имени переменной или функции. Декорированное имя — это имя, которое ищет компоновщик для разрешения внешних символов. Поскольку сведения о типе становится частью декорированного имени символа, может привести LNK2019, если объявление внешний символ, где используется не соответствует объявлению символа, где он определен. Чтобы помочь определить причину ошибки, сообщение об ошибке показано, как «понятное имя, «имя, используемое в исходный код и декорированное имя (в скобках) неразрешенный внешний символ. Не нужно знать, как перевести декорированное имя, чтобы иметь возможность сравнить его с другим декорированные имена.

Читайте также:  Проблемы с учетной записью скайп

Распространенные проблемы

Ниже приведены некоторые распространенные проблемы, вызывающие ошибку LNK2019.

Объектный файл или библиотеку, которая содержит определение символа не связаны. В Visual Studio убедитесь, что исходный файл, содержащий определение построения и связать как часть проекта. В командной строке убедитесь, что исходный файл, содержащий определение компилируется и включение в список файлов, чтобы связать файл результирующего объекта.

Объявления символа не написано таким же, как определение символа. Проверьте правильность написания и регистр символов в объявление и определение, и везде, где используется символ или именем.

Используется функция, но тип или число параметров не соответствует определению функции. Объявление функции должно соответствовать определению. Убедитесь в том, что вызов функции совпадает с объявлением, а объявление совпадает с определением. Код, который вызывает функции шаблона, также должен иметь совпадающие объявления функции шаблона, включающие те же параметры шаблона, что и определение. Пример несоответствия объявление шаблона см. Образец LNK2019e.cpp в разделе «примеры».

Функция или переменная объявлена, но не определен. Это обычно означает объявление существует в файле заголовка, но отсутствует соответствующее определение реализуется. Для функций-членов и статических элементов данных реализация должна содержать селектор области класса. Пример см. в разделе Missing Function Body or Variable.

Соглашение о вызовах различается в объявлении и определении функции. Соглашения о вызовах ( __cdecl, __stdcall, __fastcallили __vectorcall) кодируются в составе декорированного имени. Убедитесь в том, что соглашение о вызовах одно и то же.

Символ определен в файле C, но объявлен без использования extern «C» в файле C++. Декорированные имена символов, определенные в файле, который компилируется как C, будут отличаться от имен символов, объявленных в файле C++, до тех пор, пока не будет использоваться модификатор extern "C" . Убедитесь в том, что объявление соответствует компоновке компиляции для каждого символа.

Аналогично, если символ определяется в файле C++, который будет использоваться программой C, в определении следует использовать extern "C" .

Символ определяется как статический и затем используется вне файла. В C++, в отличие от C, глобальные константы имеют компоновку static . Чтобы обойти это ограничение, можно включить инициализации const в заголовок файла и ввести этот заголовок в CPP-файлы или можно присвоить переменной неконстантное значение и использовать для доступа к ней константную ссылку.

Не определен статический член класса. Статический член класса должен иметь уникальное определение. В противном случае он будет нарушать правило одного определения. Статический член класса, который не может быть определен как встроенный, должен быть определен в одном исходном файле с помощью его полного имени. Если он не определен вообще, компоновщик создает ошибку LNK2019.

Зависимость сборки определена только как зависимость проекта в решении. В более ранних версиях Visual Studioэтого уровня зависимости было достаточно. Однако начиная с Visual Studio 2010 для Visual Studio требуется ссылка одного проекта на другой. Если в проекте отсутствует ссылка на другой проект, может возникнуть эта ошибка компоновщика. Чтобы устранить ошибку, добавьте ссылку одного проекта на другой.

Построение консольного приложения выполняется с использованием параметров для приложения Windows. Если появилось сообщение об ошибке похожее на unresolved external symbol WinMain referenced in function function_name , выполните компоновку с помощью /SUBSYSTEM:CONSOLE вместо /SUBSYSTEM:WINDOWS. Дополнительные сведения об этом параметре и инструкции о том, как задать это свойство в Visual Studio, см. в статье /SUBSYSTEM (Specify Subsystem).

Использовать разные параметры компилятора для встраивания функции в различных исходных файлах. Использование встроенных функций, определенных в CPP-файлах, и смешение в различных исходных файлах параметров компилятора для встраивания функций может привести к возникновению ошибки LNK2019. Для получения дополнительной информации см. Function Inlining Problems.

Читайте также:  Как посмотреть чем загружен процессор

Автоматические переменные используются за пределами их области. Автоматические переменные (области видимости функции) могут использоваться только в области видимости данной функции. Эти переменные не могут объявляться extern и использоваться в других исходных файлах. Пример см. в разделе Automatic (Function Scope) Variables.

Вызов встроенных функций или передача типов аргументов во встроенные функции, которые не поддерживаются в целевой архитектуре. Например, если используется встроенная функция AVX2, но не указан параметр компилятора /ARCH:AVX2 , компилятор предполагает, что встроенная функция является внешней. Вместо создания встроенной инструкции компилятор создает вызов внешнего символа с тем же именем, что и у встроенного. Когда компоновщик пытается найти определение этой отсутствующей функции, он создает ошибку LNK2019. Убедитесь в том, что используются только встроенные функции и типы, поддерживаемые целевой архитектурой.

Создайте код, который использует собственный тип wchar_t с кодом, который не. Действия по согласованности языка C++, выполненные в Visual C++ 2005, привели к созданию собственного типа wchar_t по умолчанию. Для создания кода, совместимого с файлами библиотек и объектов, скомпилированными с помощью предыдущих версий Visual C++, необходимо использовать параметр компилятора /Zc:wchar_t- . Если с использованием тех же параметров /Zc:wchar_t была скомпилирована только часть файлов, разрешение ссылок на тип в совместимые типы может не быть выполнено. Убедитесь в том, что типы wchar_t во всех файлах библиотек и объектов являются совместимыми. Для этого обновите используемые типы или используйте согласованные параметры /Zc:wchar_t при компиляции.

Дополнительные сведения о возможных причинах возникновения ошибки LNK2019 и способах ее устранения см. в информации по вопросу Что представляет собой ошибка неопределенной ссылки или неразрешенного внешнего символа и как ее устранить?на StackOverflow.

Средства диагностики

Выяснение причин, по которым компоновщику не удается найти определение конкретного символа, может оказаться трудной задачей. Часто проблема заключается в том, что код не был включен в состав сборки или параметры сборки создали различные декорированные имена для внешних символов. Существует несколько средств и параметров, которые помогут диагностировать ошибку LNK2019.

С помощью параметра компоновщика /VERBOSE можно определить, на какие файлы ссылается компоновщик. Это поможет проверить, включен ли файл, содержащий определения символа, в сборку.

Параметры /EXPORTS и /SYMBOLS служебной программы DUMPBIN помогут определить, какие символы определены в DLL-файлах и файлах объекта или библиотеки. Убедитесь в том, что экспортированные декорированные имена совпадают со ссылками, которые ищет компоновщик.

Служебная программа UNDNAME может показывать эквивалентный недекорированный внешний символ для декорированного имени.

Примеры

Далее приводится несколько примеров кода, вызывающего ошибку LNK2019, а также сведения о том, как устранить ошибку.

Символ объявлен, но не определен.

В следующем примере показано возникновение ошибки LNK2019 вследствие того, что внешний символ объявлен, но не определен.

Вот другой пример.

Если i и g не определены в одном из файлов в сборке, компоновщик создает ошибку LNK2019. Чтобы исправить ошибки, включите файл исходного кода, который содержит определения, в процесс компиляции. Как вариант, можно передать в компоновщик OBJ- или LIB-файлы, которые содержат определение.

Статические данные-член объявлены, но не определены

Ошибка LNK2019 также может возникнуть в том случае, если статические данные-член объявлены, но не определены. В следующем примере показано возникновение ошибки LNK2019 и приводятся сведения по ее устранению.

Параметры объявления не соответствуют определению

Код, который вызывает функции шаблона, должен иметь совпадающие объявления функции шаблона. Объявления должны содержать те же параметры шаблона, что и определение. В следующем примере показано возникновение ошибки LNK2019 для определяемого пользователем оператора и приводятся сведения по ее устранению.

Несогласованные определения типа wchar_t

В следующем примере показано создание библиотеки DLL с экспортом, использующим WCHAR , который разрешается в wchar_t .

Следующий пример использует библиотеку DLL в предыдущем примере и создает ошибку LNK2019, поскольку неподписанные типы short * и WCHAR* не совпадают.

При попытке сборки программы появляется сообщение об ошибке одного из следующих видов:

  • ссылка на неразрешенный внешний символ .
  • неопределённая ссылка на символ .
  • unresolved external symbol .
  • undefined reference to .

Что это значит, и как исправить такую ошибку?

Читайте также:  Как войти в интернет эксплорер

2 ответа 2

Определение:

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

К таким сущностям может относиться, например, функция или переменная.

Причины и решения:

Возможных причин появления ошибки может быть несколько и это зависит от того, что представляет из себя собираемый проект. Всё множество ситуаций можно разбить на две большие группы:

Используются сторонние библиотеки

Не указана необходимая (статическая) библиотека для компоновщика.

Например, к проекту подключен только *.h файл с объявлениями, но отсутствует код реализации, обычно это *.lib или *.a файлы (в зависимости от используемой системы). Требуется явно подключить библиотеку к проекту.

Для Visual C++ это можно сделать добавлением следующей строки прямо в код:

Для gcc/clang требуется указать файл через ключ -l (эль)

Для Qt в .pro файле нужно использовать переменную LIBS :

Для системы сборки cmake есть target_link_libraries .

Библиотека указана, но необходимая сущность, например, класс или функция фактически не экспортируется из библиотеки. Под Windows это может возникать из-за отсуствия __declspec(dllexport) перед сущностью. Обычно это решается макросами. Данная ситуация чаще всего характерна именно для библиотек, находящихся в процессе разработки, и доступных для модификации самому разработчику, нежели для каких-то стабильных версий действительно внешних для проекта библиотек. После разрешения экспортирования библиотеку, конечно же, нужно пересобрать перед непосредственным использованием проблемной сущности.

Библиотека указана, но не совпадает разрядность библиотеки и компилируемого кода.

В общем случае, разрядность собираемого проекта (приложения или библиотеки) должна совпадать с разрядностью используемой сторонней библиотеки. Обычно производители библиотек предоставляют возможность выбора 32 или 64 бит версию использовать. Если библиотека поставляется в исходных кодах и собирается отдельно от текущего проекта, нужно также выбрать правильную разрядность.

Библиотека указана, но она собрана для другой (не совместимой) ОС.

Например при сборке проекта в Windows осуществляется попытка использовать бинарный файл, собранный для Linux. В данном случае нужно использовать файлы, подходящие для вашей ОС.

Библиотека указана, но она собрана другим компилятором, не совместимым с используемым.

Объектные файлы, полученные путем сборки C++ кода разными компиляторами для одной и той же ОС могут быть бинарно несовместимы друг с другом. Требуется использовать совместимые (скорее всего и вовсе одинаковые) компиляторы.

Библиотека указана, и собрана тем же компилятором, что и основной проект, но используются разные версии Run-Time библиотек.

Например, для Visual C++ возможна ситуация, когда библиотека собрана с ключом /MDd , а основной проект с /MTd . Требуется задать ключи так, чтобы использовались одинаковые версии Run-Time библиотек.

Сторонние библиотеки не используются

Просто отсутствует определение функции.

Требуется добавить определение функции f :

Может быть ещё частный случай с ошибкой вида:

Такая ошибка возникает, если объявленная виртуальная функция класса, не являющаяся чистой ( =0 ), не содержит реализации.

Нужно такую реализацию добавить. Если это делается вне класса, надо не забыть указать имя проблемного класса, иначе это будет просто свободная функция, которая не устраняет указанную проблему:

Аналогичная ситуация может возникать при использовании пространств имён, когда объявлении функции находится в пространстве имён:

а при реализации указать это пространство имён забыли:

Отсутствует определение статической переменной класса.

Нужно добавить определение (выделить память) переменной:

Неправильная реализация шаблонного кода.

Например, реализация шаблонного кода помещена в *.cpp файл, хотя она должна находиться полностью в подключаемом *.h файле.

Файл с кодом не был скомпилирован.

Например, в случае использования make-файла не было прописано правило построения файла, а в случае использования IDE типа Visual Studio *.cpp файл не добавлен в список файлов проекта.

Виртуальная функция в базовом классе не объявлена как =0 (pure-virtual).

При использовании иерархии классов функция в базовом классе, не имеющая реализации должна быть помечена как "чистая":

Имя не имеет внешнего связывания.

Например, есть объявление функции f в модуле А и даже ее реализация в модуле B , но реализация помечена как static :

Аналогичная ситуация может возникнуть при использовании безымянного пространства имен:

Рекомендуем к прочтению

Добавить комментарий

Ваш адрес email не будет опубликован.