2015-11-17 3 views
0

В Visual Studio 2012 У меня есть небольшой консоли C++ проект следующим кодомПочему ошибка LNK2005 исчезла?

main.cpp:

#include "../TestLib/LibFunction.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int number = libFunction(7); 
    return 0; 
} 

и в статическом проекте библиотеки LibTest У меня есть LibFunction.h:

#pragma once 

int libFunction(int a); 

LibFunction.cpp

int libFunction(int a) 
{ 
    return a + 1; 
} 

Это компилируется и работает нормально. (Библиотека добавляется в качестве ссылки и связаны неявно)

Если я теперь добавить этот код в основной проект

int libFunction(int a) 
{ 
    return 7 * a; 
} 

, когда я пытаюсь построить программу, которую я получаю эту ошибку

Main.obj: ошибка LNK2005: "INT __cdecl libFunction (целое)" уже определено в TestLib.lib (LibFunction.obj)

, который является достаточно справедливым (libFunction @@ YAHH @ Z?). Однако, если я сейчас просто попробую снова построить (ничего не делая), ссылка завершится без ошибок, и программа будет работать с новой используемой libFunction.

Почему ошибка исчезает? Почему это несоответствие? Либо он может переопределить функцию в библиотеке, либо ее нет. Я не должен ошибаться, а потом ничего не получаю.

Я пытаюсь понять поведение для гораздо более крупного проекта, где снова есть повторяющиеся символы, определенные в exe и ссылки lib, а иногда я получаю ошибки, а иногда и нет.

+0

Похож на ошибку в вашей toolchain. Как правило, это недействительно для переопределения функций библиотеки. Даже если линкер * иногда * преуспевает, нет гарантии того, какая реализация будет разрешена, если вы не найдете способ сообщить компоновщику. – Kenney

+1

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

+0

@ n.m - Да - отключение инкрементных результатов здания в сборке, которая последовательно не вызывает ошибок. Вы хотите добавить ответ, чтобы я мог его принять? –

ответ

1

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

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

+0

Ваша мысль о том, «если код содержит несколько внешних функций, то вам нужно переопределить их все», был фактическим ответом на мою большую проблему. –

Смежные вопросы