Серьезность код описание проект файл строка состояние подавления ошибка lnk2005 main уже определен

  • узнать, какая из двух библиотек вам действительно нужна
  • узнайте, как рассказать компоновщику не использовать другой (используя, к примеру, отзыв от Джеймса Хопкина).

xtofl 05 дек. 2008, в 11:19
Поделиться

+1 Хороший вопрос — я не совсем правильно прочитал ошибку. У меня недавно была похожая ошибка компоновщика, когда опция библиотек MFC загадочным образом включилась.

James Hopkin 05 дек. 2008, в 11:20
Точное объяснение. Спасибо за это. 🙂
mahesh 05 дек. 2008, в 11:41

Отсутствует детализация — некоторые библиотеки определяют слабые связи, при определении правильного порядка включения библиотеки сначала будет использоваться mfc, а затем — msvcrt, и поэтому тихо отбрасывает слабую связь

Greg Domjan 19 сен. 2012, в 16:09
Показать ещё 1 комментарий

У меня было такое же сообщение об ошибке, но ни один из ответов здесь не разрешил для меня. Поэтому, если вы столкнулись с этой проблемой при создании DLL-проекта, который использует MFC, его можно решить, введя следующую строку:

How to Fix Include Path Error in C/C++ Files using Visual Studio Code


extern «C»

в файл cpp, где DllMain определен. Затем используется ваша собственная реализация DllMain , а не одна из dllmain.obj.

Когда мы пытаемся использовать библиотеку MFC, мы обязательно включим afx.h напрямую или косвенно, то MFC (afx.h) сообщает компоновщику, чтобы найти символ __afxForceUSRDLL и поместите этот объект, который содержит __afxForceUSRDLL в программу, поэтому линкер выполняет поиск и помещает dllmodule.obj в наш потому что __afxForceUSRDLL определяется в dllmodule.cpp.

Это общий сценарий. Когда мы хотим использовать наш собственный DllMain в mfc dll project, компоновщик жалуется, что есть два DllMain, один в наш код, один в Dllmodule.obj.

Итак, нам нужно сказать компоновщику, чтобы добавить наш dllmain.obj для __afxForceUSRDLL. Поэтому нам нужно определить __afxForceUSRDLL в нашем собственном файле cpp, где определен наш собственный DllMain, тогда компоновщик будет игнорировать mfcs dllmodule.obj и видеть только один DllMain и никогда не жалуется.

Constantin 12 нояб. 2013, в 14:33
Поделиться
Grant 13 нояб. 2013, в 04:39
работал для меня, я использую VS2010.
zhaorufei 19 фев. 2014, в 04:59

Отлично . у меня это тоже сработало. Спасибо за совет.
jaklucky 03 март 2014, в 17:23
Работал как шарм . от этой ошибки всегда трудно избавиться. Большое спасибо.

Ram 06 июнь 2014, в 06:51

Большое спасибо, это действительно помогло. Я получал сообщение об ошибке для extern «C» в VS2015, поэтому я добавил #define перед ним, и теперь он работает как шарм 🙂

user4710450 17 янв. 2016, в 17:41

Работал для меня с VS2008 и DLL, где я вызвал ошибку соединения, используя коллекции MFC, в частности CMapStringToString.

osullivj 09 фев. 2016, в 17:00
Я удалил //AFX_MANAGE_STATE(AfxGetStaticModuleState()); stackoverflow.com/a/9070135/1641556
Elshan 19 апр. 2016, в 06:29

Для кода, который должен компилироваться как 32-битный и 64-битный, используйте этот #ifdef X86 extern «C» #else extern «C» #endif

LNK2019

JonDrnek 02 янв. 2018, в 18:57
Anurag S Sharma 22 май 2018, в 08:33
Показать ещё 7 комментариев

Если вы определяете свой собственный DllMain, в настройках вашего проекта вам нужно установить «Использовать MFC» в «Свойства конфигурации/Общие» для «Использовать стандартные библиотеки Windows».

Вы должны сделать чистую перестройку после ее изменения.

James Hopkin 05 дек. 2008, в 10:40
Поделиться

У меня есть чистая C, не MFC DLL, установленная на «Использовать стандартные библиотеки Windows», но ошибка все еще появляется.

Timothy Gu 15 март 2015, в 23:58
Я тоже. VS2010.
AlastairG 26 янв. 2018, в 14:52

Я обнаружил, что удаление _WINDOWS из препроцессора определяет в настройках проекта -> C / C ++ -> Препроцессор избавился от ложной ссылки на MSVCRTD.lib. Я использую VS2010.

ulatekh 28 фев. 2018, в 21:29
Показать ещё 1 комментарий

Для меня прямая причина была действительно отсутствующей ссылкой на символ _afxForceUSRDLL, но косвенной причиной было отсутствие определения макроса _USRDLL. Он определяется по умолчанию мастером VC, но иногда разработчики стирают его ошибочно. Вот несколько слов.

Ofek Shilon 06 май 2015, в 05:49
Поделиться

У меня было наоборот! У меня был мошенник _USRDLL в препроцессоре, который должен был быть _LIB. Doh!

TinyRacoon 31 март 2016, в 09:47

В моем проекте я смог решить эту проблему, добавив mfcs80.lib и msvcrt.lib в качестве дополнительных зависимостей в настройках проекта. «Дополнительные зависимости» можно найти в Linker → Input.

В конфигурации отладки, которая должна быть mfcs80d.lib и msvcrtd.lib соответственно.

Кстати, я работаю с Visual Studio 2010, поэтому в моем случае MFC lib называется mfc100.lib.

Я не уверен, почему это сработало. Нет необходимости добавлять эти файлы lib в качестве дополнительных зависимостей, потому что я уже установил «Использование MFC» в «Использовать MFC в общей DLL». Я предполагаю, что, указав эти библиотеки в качестве дополнительных зависимостей, они связаны в другом порядке.

Это решение более или менее совпадает с тем, которое предлагается на сайте Microsoft: http://support.microsoft.com/kb/148652, за исключением того, что мне не нужно вводить все в поле «Игнорировать конкретные библиотеки по умолчанию».

vmb100 05 июль 2012, в 13:59
Поделиться
Ссылка, которую вы предложили, помогла мне найти решение. Стоит прочитать.
TinyRacoon 31 март 2016, в 09:06

Для всех тех, кто испытывает эту ошибку в проектах ATL (в основном при попытке добавить поддержку MFC), вот решение, которое я нашел после нескольких дней разочарования!

Прежде всего, эта ссылка была для меня более полезной, чем все остальные. Он указал мне в правильном направлении. Проблема возникает, если по какой-то причине «сгенерированные файлы» (содержащие прокси-сервер и код-заглушки, так же как и типы) были удалены и прочитаны в проекте. Это заставляет Visual Studio добавлять их в неправильном порядке!

Обычно вы сначала сталкиваетесь с ошибкой «ATL требует компиляции С++», но вы можете исправить это, отключив параметр Yc/Yu (предварительно скомпилированные заголовки) для этого файла.

Что вы должны сделать дальше, это разгрузить проект и отредактировать его. Найдите группы товаров, которые определяют порядок сборки и включают порядок ( ClCompile и ClInclude ). Проверьте их порядок и настройки.

Компиляторы должны отображаться в следующем порядке:

  • dllmain.cpp (с CompileAsManaged установлено значение false и PrecompiledHeader осталось пустым).
  • Источник библиотеки ( MyLib.cpp , содержащий DllCanUnloadNow и т.д.)
  • Код прокси-сервера ( MyLib_i.c ; с теми же настройками, что и dllmain.cpp )
  • stdafx.cpp (с PrecompiledHeader установлено значение Create )
  • Все остальные исходные файлы библиотеки (фактическое содержимое библиотек)
  • xdlldata.c (с теми же настройками, что и dllmain.cpp )

Затем заказы должны быть упорядочены следующим образом:

  • dllmain.h
  • MyLib_i.h
  • Resource.h
  • stdafx.h
  • targetver.h
  • . (фактические заголовки библиотек)
  • xdlldata.h

Фиксирование порядка сборки зафиксировал мой проект, и я смог создать новую чистую сборку.

Carsten 13 янв. 2015, в 10:19
Поделиться

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

Nick 31 окт. 2016, в 18:21

Идентификатор базы знаний MSDN Q148652.

Причина: Visual С++ компилирует исходные файлы в алфавитном порядке и передает скомпилированные объектные файлы в компоновщик в алфавитном порядке. Если компоновщик сначала обрабатывает DLLDATAX.OBJ, исходный код ссылается на DllMain, который компоновщик загружает из MSVCRTD.LIB(dllmain.obj). Затем компоновщик обрабатывает объектный файл, скомпилированный из файла С++, который содержит #include «stdafx.h», который ссылается на символ __afxForceUSRDLL, который компоновщик загружает из MFC42D.LIB(dllmodul.obj). Этот объектный модуль также содержит реализацию для DllMain, вызывая конфликт.

Источник: overcoder.net

Ошибка средств компоновщика LNK2005

За этой ошибкой следует Неустранимая ошибка LNK1169.

Возможные причины и решения

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

Ниже приведены некоторые распространенные причины этой ошибки.

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

// LNK2005_global.h int global_int; // LNK2005

  • Объявите переменную extern в файле заголовка: extern int global_int; , затем определите ее и при необходимости инициализируйте ее в одном и только одном исходном файле: int global_int = 17; . Теперь эта переменная является глобальной, которую можно использовать в любом исходном файле путем объявления ее extern , например, путем включения файла заголовка. Мы рекомендуем использовать это решение для переменных, которые должны быть глобальными, но хорошей практикой разработки программного обеспечения является сокращение числа глобальных переменных.
  • Объявите переменную static: static int static_int = 17; . Это ограничивает область определения текущим объектным файлом и позволяет нескольким файловым файлам иметь собственную копию переменной. Не рекомендуется определять статические переменные в файлах заголовков из-за возможности путаницы с глобальными переменными. Предпочитают перемещать определения статических переменных в исходные файлы, которые их используют.
  • Объявите переменную selectany: __declspec(selectany) int global_int = 17; . Это предписывает компоновщику выбрать одно определение для использования всеми внешними ссылками и отменить остальные. Это решение иногда полезно при объединении библиотек импорта. В противном случае мы не рекомендуем использовать его как способ избежать ошибок компоновщика.

// LNK2005_func.h int sample_function(int k) < return 42 * (k % 167); >// LNK2005

  • inline Добавьте ключевое слово в функцию:

// LNK2005_func_inline.h inline int sample_function(int k)
// LNK2005_func_decl.h int sample_function(int);
// LNK2005_func_impl.cpp int sample_function(int k)
// LNK2005_member_outside.h class Sample < public: int sample_function(int); >; int Sample::sample_function(int k) < return 42 * (k % 167); >// LNK2005

Чтобы устранить эту проблему, переместите определения функций члена внутри класса. Функции-члены, определенные внутри объявления класса, неявно встроены.

// LNK2005_member_inline.h class Sample < public: int sample_function(int k) < return 42 * (k % 167); >>;
oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject already defined in uuid.lib(go7.obj)

Источник: code-live.ru

Какие #includes в main.cpp следует использовать (LNK2005 уже определен)

Когда я запускаю свою программу, я получаю следующие ошибки:

Я думаю, это связано с тем, что в main.cpp я пишу #include «Buffer.cpp», но я не знаю, как это сделать без этого #include. Как я могу использовать объекты Buffer, если я не есть это #include?

crende 4 Ноя 2016 в 14:01

Вы правы в том, где проблема. Включить buffer.h вместо buffer.cpp ? В файле .cpp требуется только объявление типов/функций, определение может быть в отдельном файле.

4 Ноя 2016 в 14:04
Martin Bonner supports Monica
4 Ноя 2016 в 14:06
Вам не нужно объявлять WAV_HEADER — вам нужно определить его (#включая buffer.h).
Martin Bonner supports Monica

4 Ноя 2016 в 15:07

3 ответа

Главное должно начаться

#include «Buffer.h»

Так что у него есть определение класса (но не определение всех функций-членов). Вы почти никогда не хотите #include файлы .cpp.

Это приведет к дальнейшим ошибкам, потому что вы используете типы в Buffer.h, которые вы там не определили. Исправление для этого состоит в том, чтобы определить их, поместив

#include «MonoSample.h»

В начале Buffer.h.

Martin Bonner supports Monica 4 Ноя 2016 в 15:09
Я бы сказал никогда не включать файлы .cpp. «Почти» добавляет много смысла.
4 Ноя 2016 в 14:05

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

Martin Bonner supports Monica
4 Ноя 2016 в 14:08

Источник: question-it.com

Русские Блоги

Язык C: ошибки и решения LNK2005 и LNK1169 из-за #include * .c / .cpp в среде VS

Язык C: ошибки и решения LNK2005 и LNK1169 из-за #include в среде VS

  • Предисловие (пропускается)
  • описание проблемы
  • Альтернативный метод (пропускаемый)
  • Метод слияния
  • исключение

Предисловие (пропускается)

Сегодня, когда пишу программу обработки данных, так как количество строк кода влияет на чтение и запись, я хочу переместить некоторые основные функции обработки в другой файл. Идеал очень полный, реальность очень тонкая, я переместил некоторые функции из a.cpp (псевдоним) в b.cpp (псевдоним), затем добавил #include в начале a.cpp и соответствующий extern Имя функции (переменная); После отладки она сразу пошла не так, соответственно LNK2005 и LNK1169. После долгой проверки я не обнаружил никаких ошибок, и повторных определений переменных не было.

описание проблемы

Ссылка на файл содержит #include , а указанный файл содержит функции. При компиляции компилятор выдавал ошибки LNK2005 и LNK1169. Функция была определена в * .obj, и был найден один или несколько символов с несколькими определениями.

Часть программы:
Прямая цитата (включая) .c или .cpp файлы
 1
И оба находятся в одном проекте(ерунда)
 2
И есть функция во включенном файле
 3
Часть ошибки компилятора:
LNK1169LNK2005

Альтернативный метод (пропускаемый)

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

Метод слияния

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

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

исключение

Этот метод проще, и включенный файл напрямую удаляется из решения, но #include не следует изменять, а файл не следует перемещать, например так:

 2
Отладка также может проходить:
 3
Это удивительно? Немного проблематично не открывать другой файл в том же окне управления ресурсами во время программирования.

анализ проблемы

После двух вышеупомянутых тестов мы заметили, что источник проблемы связан с двумя файлами в одном решении. И когда код двух файлов помещается в один и тот же файл, ссылка на компиляцию не выдаст ошибку. так чтоОшибка связана с обработкой #include .И не имеет ничего общего с функцией самого кода.
На языке C #include будет вставлять указанный файл в исходный файл, Это эквивалентно нашему методу слияния.Однако при компиляции VS каждый файл .cpp или .c в решении будет компилироваться отдельно, только файл .h — нет. После компиляции в файл .obj VS связывает все файлы .obj вместе, чтобы создать файл .exe. Поэтому, если на a.cpp есть прямая ссылка на b.cpp, после компиляции будет сгенерирован a.obj, содержащий контент a + b, и b.obj, содержащий контент b. В это время, когда VS снова установит связь, вы обнаружите, что файл a.obj содержит повторяющиеся определения функций (или определения переменных) с b.obj, поэтому возникают ошибки LNK2005 и LNK1169.

Решение

Решение состоит в том, чтобы использовать ключевое слово extern, чтобы предложить компилятору найти свое определение в других файлах, когда он встречает эту переменную или функцию. Вместо непосредственного использования #include , такого как добавление объявления функции b.c в a.c: следующим образом:

extern bool Output_Structure(struct person* n); extern long Get_File_Size(FILE* File);

 2

Затем вы можете использовать эти функции непосредственно в a.c. Если вам нужно использовать несколько файлов, вы можете поместить код объявления в файл заголовка, так что вам нужно только сослаться на файл заголовка.

Как показано на рисунке, ссылка на компиляцию прошла успешно.

 1

Резюме и рефлексия

C

Должен быть разработан механизм, при котором файлы, вставленные во время компиляции, больше не будут компилироваться, но на самом деле мне нечего делать. Я всегда чувствую, что это решение приводит к тому, что длина кода становится больше, чем раньше, что серьезно влияет на производительность программы.В этом решении все еще есть много недостатков. Я надеюсь, что если у вас есть лучший способ оставить сообщение ниже, я отвечу вам в любое время. Спасибо.
Примечание. Согласно сообщению в блоге, что убийца из зыбучих песков отреагировал на ту же проблему, проблема также существует в VS6.0, и я получаю ошибку, созданную в среде VS2019,Следовательно, можно считать, что эта ошибка распространена во всей среде VS.
Примечание. После фактического тестирования файл #include также выдаст ту же ошибку, которая также может быть устранена тем же методом,Поэтому считается, что эта ошибка появится на языке Си / Си ++, и решение остается тем же.

Источник: russianblogs.com

Рейтинг
( Пока оценок нет )
Загрузка ...