Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 5.00
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
#1

Ошибки линковки LNK2005, LNK1169 - C++

04.04.2012, 18:19. Просмотров 3260. Ответов 20
Метки нет (Все метки)

Как-то пробовал сделать программу из нескольких модулей, но наткнувшись на какие-то непонятные ошибки забросил это дело...
Решив же намедни окончательно разобраться с этим вопросом, я опять столкнулся с непонятными ошибками линковки, поиск чётких ответов не дал.
Что же тут не так?

Файл Example.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef EXAMPLE_CPP
#define EXAMPLE_CPP
 
#include <string>
#include <iostream>
 
int out_string1(std::string str)
{
    std::cout << str << 1 << std::endl;
    return true; 
}
 
using namespace std;
void out_string2(string str)
{
    cout << str << 2 << endl;
}
 
#endif
Главный файл с мейном:

C++
1
2
3
4
5
6
7
8
9
#include "Example.cpp"
 
 
void main()
{
    out_string1("ololo");
    out_string2("test");
    system("pause");
}
1>ManifestResourceCompile:
1> All outputs are up-to-date.
1>Test.obj : error LNK2005: "int __cdecl out_string1(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?out_string1@@YAHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) уже определен в Example.obj
1>Test.obj : error LNK2005: "void __cdecl out_string2(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?out_string2@@YAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) уже определен в Example.obj
1>C:\Users\User_name\Desktop\Test\Debug\Test.exe : fatal error LNK1169: обнаружен многократно определенный символ - один или более
Среда VS 10.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.04.2012, 18:19
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ошибки линковки LNK2005, LNK1169 (C++):

Ошибка линковки файлов при компиляции: "fatal error LNK1169: обнаружен многократно определенный символ" - C++
Visual C++ 2008 Express Edition ошибка Компиляция... 1.cpp Компоновка... 2.obj : error LNK2005: &quot;int __cdecl GetByte(int)&quot;...

Объясните доступно и просто возможные причины возникновения ошибки линковщика - LNK2005 - C++
Объясните доступно и просто возможные причины возникновения ошибки линковщика - LNK2005.

ошибки линковки с++(... - C++
помогите пожалуйста!! справится с ошибками линковки масив.obj : error LNK2001: unresolved external symbol &quot;void __cdecl obr(int &amp;,int *)&quot;...

Ошибки линковки - C++
Нужна помощь! Как исправить эти ошибки при компиляции! Все либы и заголовки дополнительные указаны он вроде их не требует! Я даже не...

Ошибки на стадии линковки - C++
obj\Release\main2.o:main2.cpp|| undefined reference to `__gxx_personality_sj0'| obj\Release\main2.o:main2.cpp|| undefined reference to...

[MPI] Ошибки линковки - C++
Надо было написать проект который складывает числа в массиве. И выводит сумму. Одно из требований использование MPI. Но при компиляции...

20
Kuzia domovenok
1947 / 1800 / 137
Регистрация: 25.03.2012
Сообщений: 6,234
Записей в блоге: 1
04.04.2012, 18:24 #2
#include "Example.cpp"
Никогда так не делай.
Инклудятся только заголовочные (header) файлы
#ifndef EXAMPLE_CPP
#define EXAMPLE_CPP
Это вообще смешно
Хочешь где-нибудь зачем-нибудь написать стражи включения, создай
Example.h
и в него пихай
Линкер сам найдёт твой экзампл.спп и свяжет с майном
Нужно только указать для компилятора объявления функций
C++
1
2
3
4
5
6
7
8
9
void out_string1(std::string);//эти два объявления обязательны, но 
void out_string2(std::string);//приличные люди пихают их в новый файл Example.h ивместо них здесь 
////////////////////////////////тогда будет #include "Example.h"
void main()
{
    out_string1("ololo");
    out_string2("test");
    system("pause");
}
0
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
04.04.2012, 18:41  [ТС] #3
Не помогло...
Насколько я помню расширение подключаемых файлов может быть хоть txt, тк препроцессор работает с текстовыми файлами, а какое им задать расширение это дело традиции...

Добавлено через 10 минут
Можно пример правильно оформленных файлов для успешной компиляции?
0
Kuzia domovenok
1947 / 1800 / 137
Регистрация: 25.03.2012
Сообщений: 6,234
Записей в блоге: 1
04.04.2012, 18:52 #4
Пример ща напишу, а по поводу инклуда спп
Пойми подключать в одно целое cpp файлы это работа линкера и ты ему мешаешь её выполнять
Хочешь подключить тхт? Вот и переименуй example.cpp в example.txt, извращенец
А линкер их сам соберёт, слышал понятие "раздельная компиляция"?
ща пример будет

Добавлено через 4 минуты
Файл Example.h
C++
1
2
3
#include <string>
int out_string1(std::string );
int out_string2(std::string );
Файл Example.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Example.h"
#include <iostream>
 
int out_string1(std::string str)
{
    std::cout << str << 1 << std::endl;
    return true; 
}
 
using namespace std;
void out_string2(string str)
{
    cout << str << 2 << endl;
}
Главный файл с мейном:

C++
1
2
3
4
5
6
7
#include "Example.h"
void main()
{
    out_string1("ololo");
    out_string2("test");
    system("pause");
}
1
fasked
Эксперт С++
4948 / 2528 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
04.04.2012, 18:54 #5
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Линкер сам найдёт твой экзампл.спп и свяжет с майном
Линкер не умеет сам находить файлы, которые надо связать. Для этого существуют мэйкфайлы, конфигурации проектов и другие приблуды.
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
А линкер их сам соберёт, слышал понятие "раздельная компиляция"?
Вот именно. Вы слышали?
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Файл Example.h
Инклуд гуарды для слабаков?
0
Kuzia domovenok
1947 / 1800 / 137
Регистрация: 25.03.2012
Сообщений: 6,234
Записей в блоге: 1
04.04.2012, 18:58 #6
Цитата Сообщение от fasked Посмотреть сообщение
Инклуд гуарды для слабаков?
Мне впадлу было.

Цитата Сообщение от fasked Посмотреть сообщение
Линкер не умеет сам находить файлы, которые надо связать. Для этого существуют мэйкфайлы, конфигурации проектов и другие приблуды.
Ясно. Теперь Скажи, зачем мэйкфайлы человеку пытающемуся создать первый проект из двух файлов спп в MSVS? Инклуд стражи он уже использовал не там где надо.
0
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
04.04.2012, 19:03  [ТС] #7
Kuzia domovenok, работает, сейчас буду разбираться как)

fasked, пожалуйста, если можете дополнить, я буду весьма благодарен.

Новые вопросы:
Что за инклуд гуарды?
Как же надо использовать "инклуд стражи"?
0
fasked
Эксперт С++
4948 / 2528 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
04.04.2012, 19:30 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Whiteha, include guard это те самые
C
1
2
3
4
#ifndef FILENAME_H
#define FILENAME_H
 
#endif
Защищают от множественного включения одного файла. Если, например, сделать
C
1
2
#include "something1.h"
#include "something2.h"
И в этих хэдэрах подключается один и тот же заголовочныый файл, в котором не стоят инклуд гуарды, то собрать проект не выйдет.
Так что лучше их использовать всегда.

Директива #include просто подставляет содержимое файла. Так что сами представьте, что будет, если подставить содержимое одного файла дважды. Уж точно ничего хорошего
Цитата Сообщение от Whiteha Посмотреть сообщение
Насколько я помню расширение подключаемых файлов может быть хоть txt, тк препроцессор работает с текстовыми файлами, а какое им задать расширение это дело традиции
Совершенно верно. Однако, следует помнить, что иные способы могут вызвать кучу недоразумений и непониманий. Собственно отсюда и пошли традиции - чтобы все друг друга понимали.
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Скажи, зачем мэйкфайлы человеку пытающемуся создать первый проект из двух файлов спп в MSVS? Инклуд стражи он уже использовал не там где надо.
То, что MSVS сама генерирует мэйкфайл или что-либо подобное не значит, что его нет или что этого человека можно обманывать, говоря о линкере как о всеумеющей тулзе. Это не так.

Не по теме:

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Мне впадлу было.
Я так посмотрю с Вами часто такое.

3
Kuzia domovenok
1947 / 1800 / 137
Регистрация: 25.03.2012
Сообщений: 6,234
Записей в блоге: 1
04.04.2012, 19:45 #9
Человек спросил, как "собрать проект из двух файлов в MSVS"
Конкретный вопрос. Всё. Я ему вообще не хотел сначала писать весь этот код, говорить, что объявления функций нужно выносить в заголовочные файлы, и.т.д.и.т.п. Посмотри мой первый пост. Там даже про .h файл не упомянуто.
Он не спрашивал про инклудгарды, мейк файлы, компиляцию и линковку из командной строки и прочие извращения. Даны функции, сказано построить в MSVS - я ответил. Лишняя информация только отвлекает.
0
alexey31415
59 / 59 / 3
Регистрация: 16.05.2010
Сообщений: 632
04.04.2012, 19:52 #10
Цитата Сообщение от fasked Посмотреть сообщение
И в этих хэдэрах подключается один и тот же заголовочныый файл, в котором не стоят инклуд гуарды, то собрать проект не выйдет.
то есть если в одном файле я определю код между
C++
1
2
3
4
#ifndef FILENAME_H
#define FILENAME_H
 
#endif
то во втором он уже не будет определяться,так как уже определён?
0
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
04.04.2012, 19:54  [ТС] #11
Сейчас имеется:

Интерфейс Example.h:
C++
1
2
3
4
5
6
#include <string>
#include <iostream>
 
using namespace std;
int  out_string1(string );
void out_string2(string );
Реализация Example.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "Example.h"
 
int out_string1(string str)
{
    cout << str << 1 << endl;
    return true; 
}
 
void out_string2(string str)
{
    cout << str << 2 << endl;
}

Файл с мейном:
C++
1
2
3
4
5
6
7
8
#include "Example.h"
 
void main()
{
    out_string1("ololo");
    out_string2("test");
    system("pause");
}
Файл с мейном включает в себя Example.h, using nemespace std из которого распространяется на всю остальную программу, однако по поводу Example.h и Example.cpp есть некоторые вопросы:
1) Как Example.h подключает Example.cpp?
И почему это работает, если Example.cpp вновь подключает Example.h(почему не получается бесконечная рекурсия и VS не посылает нас разбираться с ошибками)?
2) Почему при попытке вынести из Example.h
C++
1
2
#include <string>
#include <iostream>
в файл с мейном перед #include "Example.h" на нас обрушивается лес ошибок?
3) Как при данной организации файлов правильно организовать инклуд гуарды?
0
Kuzia domovenok
1947 / 1800 / 137
Регистрация: 25.03.2012
Сообщений: 6,234
Записей в блоге: 1
04.04.2012, 20:01 #12
Цитата Сообщение от alexey31415 Посмотреть сообщение
то есть если в одном файле я определю код между
C++
1
2
3
4
#ifndef FILENAME_H
#define FILENAME_H
 
#endif
то во втором он уже не будет определяться,так как уже определён?
Товарищ говорил о случаях, когда ты в один cpp прямо или косвенно подключаешь два одинаковых h файла так
C++
1
2
#include "head.h"
#include "head.h"
или так косвенно
C++
1
2
3
4
5
//main.cpp
#include "head2.h"
#include "head.h"
............
//////////////////////////
C++
1
2
3
//head2.h
#include "head.h"
..................
Но не парься, главное не пиши их больше в спп файлах. Если знаешь, что такое #ifndef - поймёшь как они работают.
Вообще, я пишу их, когда линковщик выдаёт очередную страшную LNK ошибку.
У тебя ж всего два файла! Как в них запутаешься?
0
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
04.04.2012, 20:10  [ТС] #13
Ок, значит если ставить защиту от множественного подключения, то тока в *.h, так:
Example.h
C++
1
2
3
4
5
6
7
8
9
10
11
#ifndef EXAMPLE_H
#define EXAMPLE_H
 
#include <string>
#include <iostream>
 
using namespace std;
int  out_string1(string );
void out_string2(string );
 
#endif
Так?

А как быть с 1 и 2 жизненными вопросами(Ошибки линковки LNK2005, LNK1169)?=\
0
Kuzia domovenok
1947 / 1800 / 137
Регистрация: 25.03.2012
Сообщений: 6,234
Записей в блоге: 1
04.04.2012, 20:13 #14
Цитата Сообщение от Whiteha Посмотреть сообщение
Сейчас имеется:

Интерфейс Example.h:
C++
1
2
3
4
5
6
7
8
9
#ifndef EXAMPLE_@ADEcx
#define EXAMPLE_@ADEcx
#include <string>
#include <iostream>
 
using namespace std;
int  out_string1(string );
void out_string2(string );
#endif
Реализация Example.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "Example.h"
 
int out_string1(string str)
{
    cout << str << 1 << endl;
    return true; 
}
 
void out_string2(string str)
{
    cout << str << 2 << endl;
}

Файл с мейном:
C++
1
2
3
4
5
6
7
8
#include "Example.h"
 
void main()
{
    out_string1("ololo");
    out_string2("test");
    system("pause");
}
1) Как Example.h подключает Example.cpp?
И почему это работает, если Example.cpp вновь подключает Example.h(почему не получается бесконечная рекурсия и VS не посылает нас разбираться с ошибками)?
2) Почему при попытке вынести из Example.h
C++
1
2
#include <string>
#include <iostream>
в файл с мейном перед #include "Example.h" на нас обрушивается лес ошибок?
3) Как при данной организации файлов правильно организовать инклуд гуарды?
CPP никуда друг к другу не подключаются и не должны подключаться. Они компилируются как есть в промежуточные объектные файлы. абсолютно независимо друг от друга. Все указания "вызвана внешняя функция из другого куска программы" и связывание этих кусков в единый экзешник происходят потом.
В том то и фокус, что прописывая вызов функции, тебе для успешной компиляции достаточно иметь лишь её объявление

int out_string1(string );

Вот такие объявления действительно напрямую пришиваются инклудами в спп файл,
Т.е. достаточно знать, что такая функция есть, и какой у неё синтаксис при использовании.
На место вызова ф-ии компилятор поставит переход, а адрес перехода потом определится
А уже после компиляции проект соберётся в одно целое и
0
silent_1991
Эксперт С++
4986 / 3043 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
05.04.2012, 12:55 #15
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Вообще, я пишу их, когда линковщик выдаёт очередную страшную LNK ошибку
В краевом случае, когда все файлы содержат включение всех остальных, стражи включения придётся написать везде. Так почему бы их не писать сразу?
0
05.04.2012, 12:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.04.2012, 12:55
Привет! Вот еще темы с ответами:

Ошибки линковки в двусвязном списке - C++
Помогите, пожалуйста, разобраться, в чем ошибки.. Возникают на этапе линковки, Error LNK2019 unresolved external symbol List.h #include...

Ошибки линковки std::filesystem - C++
Доброго времени суток. В общем я хотел поиграться с фишками будущего стандарта, а именно с std::experimental::filesystem. Столкнулся с...

Ошибки линковки библиотеки FLTK - C++
Добрые сутки, на данный момент я изучаю FLTK По исключительной ситуации я ничего не могу понять, проблема состоит в том что я работаю...

Ошибки линковки при работе с DirectX - C++
Создал DirectX проект, и решил разбить на файлы, создал render.cpp и main.cpp, они отвечают за разные функции, но стоит подключить к...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru