2012-01-25 5 views
2

Я создал образец проекта C++ в Visual Studio 2010 со следующими файлами.Ошибка LNK2019 в Visual Studio 2010

Ах

#ifndef A_H 
#define A_H 

#include <iostream> 

void foo(); 

#endif 

a.cpp

#include "A.h" 

void foo() 
{ 
    int a = 1; 
} 

main.cpp

#include "A.h" 

int main(int argc, char* argv[]) 
{ 
    foo();  

    return 0; 
} 

Я получаю следующий результат после сборки:

1> --- --- Начало сборки: Проект: opengl_test , Configuration: Debug Win32 ------

1> main.cpp

1> Ах

1> a.cpp

1> Создание кода ...

1> Debug \ A.obj: предупреждение LNK4042: объект, указанный более одного раза; дополнительные игнорировали

1> main.obj: ошибка LNK2019: неразрешенный внешний символ "недействительным __cdecl Foo (аннулируются)" (Foo @@ YAXXZ?) ссылка в функции _main

1> C: \ Users \ ALP \ Проекты \ Образцы тестов \ opengl_test \ Debug \ opengl_test.exe: фатальная ошибка LNK1120: 1 неразрешенные внешние данные

===================================== пропущено ==========

В чем причина этой ошибки?

+0

Возможный дубликат [Visual Studio 2010 «странное предупреждение LNK4042»] (http://stackoverflow.com/questions/3695174/visual-studio-2010s-strange-warning-lnk4042) –

+0

Для чего это стоит, я ** не может ** воспроизвести это в новом, пустом проекте в VS 2010. Я просто добавил ваши 3 файла кода ('Ah',' A.cpp' и 'main.cpp'), а затем скомпилирован. Работает нормально, никаких ошибок. Итак, вопрос в том, что отличается от вашей настройки, чем моя (и то, что вы описали в вопросе)? –

+0

@CodyGray Я создал новое решение и добавил эти файлы в проект и теперь строит без каких-либо ошибок или предупреждений. Дело в том, что проект сначала ссылался на функции opengl/glut, и в какой-то момент визуальная студия начала давать мне эту ошибку LNK2019, и она не давала ее все время, как я описал здесь http://stackoverflow.com/questions/8996385/ c-unresolved-external-symbol-error-after-clean. Затем он начал давать его всегда. Поэтому я преобразовал проект в эту простую форму, и он продолжал давать ошибку. Я не знаю, что вызвало разницу в конфигурации между двумя проектами. –

ответ

3

Я думаю, что произошло то, что A.h был в исходной группе проекта, а не в группе заголовков, поэтому он был скомпилирован, как если бы это был .cpp. Поскольку оба A.cpp и A.h будут генерировать объектный файл A.obj, последний компиляция - единственное, что связано. Я считаю, что последний компилировался: A.h, у которого не было n реализация foo(), поэтому компоновщик не смог найти его.

+0

Это кажется более разумным, чем мое объяснение. –

+0

Однако ошибка возникает после очистки проекта. Должна ли визуальная студия удалять все obj-файлы и компилироваться с новыми файлами? –

+0

@AlpHancioglu, очистка проекта - это необходимый шаг, но он перемещает 'A.h' из группы' Sources'. –

0

EDIT: Nevermind оригинальный ответ (ниже), я считаю, что вы ищете, может быть здесь: (? Не проблема, но может быть, звук советы) Visual Studio 2010's strange "warning LNK4042"

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

#ifndef A_H 
#define A_H 

#include <iostream> 

void foo(); 

#endif //A_H 
+0

Это не похоже на определение, хотя, опытный образец. Это еще один случай «C++ не работает, как C»? – sarnold

+0

@Nic Добавил их, но такую ​​же ошибку. –

+0

Хотя это, безусловно, хороший совет в целом, он не выглядит применимым к этому вопросу, поскольку OP не включает a.h в том же компиляционном блоке. – dasblinkenlight

0

Во-первых, вам нужно включить «stdafx.h» в файле «a.cpp» до линии включения «хиджры».

Во-вторых, лучше добавить «a.h» в свой проект «Заголовочные файлы» и добавить «a.cpp» в свои «Исходные файлы».

Тогда он будет скомпилирован без ошибок! Удачи.

Кстати, причина включения «stdafx.h» заключается в том, что по умолчанию проект использует предварительно скомпилированные заголовки, поэтому компилятор ищет «stdafx.h».

Если вы хотите, вы можете отключить «предварительно скомпилированный заголовок», тогда вам не понадобится «stdafx.h», и все будет хорошо.

+0

Зачем нужно включать stdafx.h? Это не визуальное приложение C++, и я не использую какие-либо классы MFC, или функции Windows API или не нацеливаю .NET. Это простое родное приложение C++. Заголовочный файл находится в разделе «Заголовки файлов», а файлы cpp находятся в разделе «Исходные файлы», как вы сказали. –

+0

@Alp: 'stdafx.h' является именем по умолчанию для предварительно скомпилированного заголовка. Он не имеет ничего общего с любой из технологий, которые вы упомянули. Но предварительно скомпилированные заголовки * optional * (хотя и включены по умолчанию), и вы можете назвать свой предварительно скомпилированный заголовок чем угодно. Так что да, эта часть ответа, скорее всего, неверна. Но ваше понимание «stdafx.h» также неверно. :-) –

+0

привет, все. вам нужно попробовать и посмотреть, не так ли или нет. На самом деле я не думал, что должен включить «stdafx.h». Но компилятор пожаловался и предложил мне включить это, и я это сделал. Бинго, это работает! –

0

Код работает, когда я создал новый проект. Я не уверен, но причиной ошибки может быть то, что я добавил папку «C: \ Program Files \ Microsoft SDKs \ Windows \ v7.1 \ Include "к включенным каталогам в настройках проекта, а Visual Studio уже включила папку" C: \ Program Files (x86) \ Microsoft SDK \ Windows \ v7.0A \ Include "(которая предназначена для 32-разрядных программ) на поэтому я добавил файлы заголовков opengl только в папку Program Files (x86), удалил include для 64-битной папки Program Files и теперь работает opengl-код.

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