Ошибка средств компоновщика LNK2005
символ , уже определенный в объекте
Символ был определен несколько раз.
За этой ошибкой следует неустранимая ошибка LNK1169.
Возможные причины и способы устранения
Как правило, эта ошибка означает, что вы нарушили одно правило определения, которое разрешает только одно определение для любого используемого шаблона, функции, типа или объекта в данном файле объекта и только одно определение всего исполняемого файла для внешних видимых объектов или функций.
Ниже приведены некоторые распространенные причины этой ошибки.
Эта ошибка может возникать, когда файл заголовка определяет переменную. Например, если этот файл заголовка включен в проект несколько исходных файлов, результаты ошибки:
// LNK2005_global.h int global_int; // LNK2005
Ниже представлены возможные решения.
Объявите переменную
extern
в файле заголовка:extern int global_int;
затем определите ее и при необходимости инициализировать ее в одном и только одном исходном файле:int global_int = 17;
Эта переменная теперь является глобальной, которую можно использовать в любом исходном файле, объявив егоextern
, например, включив файл заголовка. Мы рекомендуем это решение для переменных, которые должны быть глобальными, но хорошая практика проектирования программного обеспечения сводит к минимуму глобальные переменные.Объявите статическую переменную:
static int static_int = 17;
. Это ограничивает область определения текущим файлом объектов и позволяет нескольким файлам объектов иметь собственную копию переменной. Не рекомендуется определять статические переменные в файлах заголовков из-за возможности путаницы с глобальными переменными. Предпочитайте перемещать определения статических переменных в исходные файлы, которые используют их.Объявите переменную selectany:
__declspec(selectany) int global_int = 17;
. Это сообщает компоновщику выбрать одно определение для использования всеми внешними ссылками и отменить остальные. Это решение иногда полезно при объединении библиотек импорта. В противном случае мы не рекомендуем использовать его как способ избежать ошибок компоновщика.
Эта ошибка может возникать, когда файл заголовка определяет функцию, которая не
inline
является. Если этот файл заголовка включен в несколько исходных файлов, вы получите несколько определений функции в исполняемом файле.// LNK2005_func.h int sample_function(int k) { return 42 * (k % 167); } // LNK2005
Ниже представлены возможные решения.
Добавьте ключевое
inline
слово в функцию:// LNK2005_func_inline.h inline int sample_function(int k) { return 42 * (k % 167); }
Удалите текст функции из файла заголовка и оставьте только объявление, а затем реализуйте функцию в одном и только одном исходном файле:
// LNK2005_func_decl.h int sample_function(int);
// LNK2005_func_impl.cpp int sample_function(int k) { return 42 * (k % 167); }
Эта ошибка также может возникать, если вы определяете функции-члены вне объявления класса в файле заголовка:
// 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); } };
Эта ошибка может возникать, если вы связываете несколько версий стандартной библиотеки или CRT. Например, если вы пытаетесь связать библиотеки CRT для розничной торговли и отладки, либо статических и динамических версий библиотеки или двух разных версий стандартной библиотеки с исполняемым файлом, эта ошибка может быть сообщена много раз. Чтобы устранить эту проблему, удалите все копии каждой библиотеки из команды ссылки. Мы не рекомендуем смешивать розничные и отладочные библиотеки или разные версии библиотеки в одном исполняемом файле.
Чтобы сообщить компоновщику использовать библиотеки, отличные от значений по умолчанию, в командной строке укажите используемые библиотеки и используйте параметр /NODEFAULTLIB , чтобы отключить библиотеки по умолчанию. В интегрированной среде разработки добавьте ссылки на проект, чтобы указать используемые библиотеки, а затем открыть диалоговое окно "Страницы свойств" для проекта, а затем на странице свойств Компоновщика, входных свойств задайте свойства "Игнорировать все библиотеки по умолчанию" или "Игнорировать определенные библиотеки по умолчанию", чтобы отключить библиотеки по умолчанию.
Эта ошибка может возникать, если при использовании параметра /clr используется статические и динамические библиотеки. Например, эта ошибка может возникать, если вы создаете библиотеку DLL для использования в исполняемом файле, который связывается со статическим CRT. Чтобы устранить эту проблему, используйте только статические библиотеки или только динамические библиотеки для всего исполняемого файла и для всех библиотек, которые будут использоваться в исполняемом файле.
Эта ошибка может возникать, если символ является упакованой функцией (созданной компиляцией с помощью /Gy), и она была включена в несколько файлов, но была изменена между компиляциями. Чтобы устранить эту проблему, перекомпилируйте все файлы, включающие упаковаемую функцию.
Эта ошибка может возникать, если символ определен по-разному в двух объектах-членах в разных библиотеках, а оба объекта-члена используются. Один из способов устранить эту проблему, если библиотеки статически связаны, — использовать объект-член только из одной библиотеки и включить эту библиотеку сначала в командную строку компоновщика. Чтобы использовать оба символа, необходимо создать способ их отличия. Например, если можно создать библиотеки из источника, можно упаковать каждую библиотеку в уникальное пространство имен. Кроме того, можно создать новую библиотеку-оболочку, которая использует уникальные имена для упаковки ссылок на одну из исходных библиотек, связать новую библиотеку с исходной библиотекой, а затем связать исполняемый файл с новой библиотекой вместо исходной библиотеки.
Эта ошибка может возникать, если
extern const
переменная определена дважды и имеет другое значение в каждом определении. Чтобы устранить эту проблему, определите константу только один раз или используйте пространства имен илиenum class
определения для различения констант.Эта ошибка может возникать, если вы используете uuid.lib в сочетании с другими файлами LIB, определяющими идентификаторы GUID (например, oledb.lib и adsiid.lib). Например:
oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject already defined in uuid.lib(go7.obj)
Чтобы устранить эту проблему, добавьте /FORCE:MULTIPLE в параметры командной строки компоновщика и убедитесь, что uuid.lib является первой ссылкой на библиотеку.