Форум программистов, компьютерный форум CyberForum.ru

Ошибки линковщика - C++

Восстановить пароль Регистрация
 
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.08.2012, 10:13     Ошибки линковщика #1
Люди добрые, подскажите, как быть или дайте ссылку на статью о том, как работает линковщик..

Есть один главный хэдер, подключащий всё :

Chat Server.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef __CHATSERVER_H_
#define __CHATSERVER_H_
 
#include "resource.h"
 
#include "Defines.h"
#include "Classes.h"
#include "GlobalVariables.h"
 
#include "User.h"
#include "Room.h"
#include "Compare.h"
#include "Server.h"
#include "WndProcs.h"
 
#endif /*__CHATSERVER_H_*/


server.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "Chat Server.h"
 
#ifndef __SERVER_H__
#define __SERVER_H__
 
class SERVER
{
private :
    BOOL _s_status;
    HANDLE _s_thread;
 
    SOCKET _s_socket;
    sockaddr_in _s_address;
 
    set <USER*, COMPARE> _s_users;
    set <ROOM*, COMPARE> _s_rooms;
 
    list <BYTE> _s_usersID;
    list <BYTE> _s_roomsID;
 
public :
    SERVER();
    ~SERVER();
 
    BOOL    Start();
    BOOL    Accept();
    BOOL    Stop();
 
    USER*   UserNameUsed(char*);
    ROOM*   RoomNameUsed(char*);
 
    BOOL    SendToRoom(char*, ROOM*);
    BOOL    SendToAll(char*);
 
    BOOL    UserEnterRoom(USER*, ROOM*);
    BOOL    UserExitRoom(USER*, ROOM*);
 
    BOOL    AddUser(USER*);
    BOOL    DelUser(USER*);
    BOOL    AddRoom(ROOM*);
    BOOL    DelRoom(ROOM*);
 
    BOOL    CreateMessage(char*) const;
    BOOL    SetMessageParams(char*, const PACKET_COMMAND&, const BYTE&, const BOOL&) const;
    BOOL    GetMessageParams(const char*, PACKET_COMMAND&, BYTE&, BOOL&) const;
 
    const char* GetStatusString() const;
};
 
DWORD CALLBACK AcceptShell(LPVOID);
 
#endif /*__SERVER_H__*/


room.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "Chat Server.h"
 
#ifndef __ROOM_H__
#define __ROOM_H__
 
class ROOM
{
public :
    BOOL _r_ID;
    char* _r_name;
    set<USER*, COMPARE> _r_usersIn;
 
    ROOM();
    ~ROOM();
};
 
#endif /*__ROOM_H__*/


user.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "Chat Server.h"
 
#ifndef __USER_H__
#define __USER_H__
 
class USER
{
public :
    BOOL _u_ID;
    char* _u_name;
    HANDLE _u_thread;
    set <ROOM*, COMPARE> _u_roomsIn;
 
    sockaddr_in _u_address;
    int _u_addressSize;
    SOCKET _u_socket;
 
 
    USER();
    ~USER();
 
    BOOL Connection();
};
 
DWORD CALLBACK ConnectionShell(LPVOID);
 
#endif /*__USER_H__*/


compare.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Chat Server.h"
 
#ifndef __COMPARE_H__
#define __COMPARE_H__
 
class COMPARE
{
public :
    COMPARE();
    bool operator() (ROOM*, ROOM*) const;
    bool operator() (USER*, USER*) const;
}
 
#endif /*__COMPARE_H__*/


classes.h
C++
1
2
3
4
5
6
7
8
9
#ifndef __CLASSES_H__
#define __CLASSES_H__
 
class ROOM;
class USER;
class SERVER;
class COMPARE;
 
#endif /*__CLASSES_H__*/


И в глобальных переменных маты на экземпляр класса SERVER
server.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef __GLOBALVARIABLES_H__
#define __GLOBALVARIABLES_H__
 
#ifdef __MAIN_CPP__
#define NAMESPACE
#else /*!(__MAIN_CPP__)*/
#define NAMESPACE extern
#endif /*__MAIN_CPP__*/
 
NAMESPACE WNDCLASSEX wcex;
NAMESPACE HWND hWndMain;
NAMESPACE HWND hDlgMain;
NAMESPACE HINSTANCE hInstMain;  
NAMESPACE WSADATA wsaData;
NAMESPACE TCHAR szTitle[STRING_SIZE];                   
NAMESPACE TCHAR szWindowClass[STRING_SIZE]; 
NAMESPACE SERVER server;
 
#endif /*__GLOBALVARIABLES_H__*/


В каждом cpp-файле есть только :
C++
1
2
#include "stdafx.h"
#include "Chat Server.h"
Собственно я запутался. 165 ошибок о том, что не определен SERVER, хоть и объявлен, о том, что не имеют ROOM'ы поля, да и вообще без 100 граммпонятия работы линковщика не разобраться

Добавлено через 2 часа 31 минуту
up-to-date
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
29.08.2012, 12:56     Ошибки линковщика #2
возможно все из-за того, что в compare.h в 12 строке пропущена ;
по хорошему нужны спп файлы и все ошибки.

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



C++
1
2
3
4
5
6
7
8
9
10
// Chat Server.h
....
#include "Server.h"
....
 
 
 
// Server.h
#include "Chat Server.h"
....
Какое-то рекурсивное включение


нигде не увидел #include <set>



По хорошему в каждый файл должен включатся минимальный необходимый набор инклудов, а не так как у вас, свалено все в один файл и потом он везде прописан. типа так проще. на самом деле так делать не стоит.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.08.2012, 13:25  [ТС]     Ошибки линковщика #3
DU, искал слона, а вот мышь(";") то и не увидел.. Поменял местами в char server.h пару инклюдов и все стало нормально : )
Set объявлен в stdafx. Об этом забыл написать.
С константами пока не заморачивался, ибо это уже косметический эффект. Сейчас бы заставить хотя бы запускаться.
А разве компилятор включает полностью хэдеры, даже если что-то из них не используется?
Насчет "рекурсивного включения" - так я делал раньше, чтобы можно было объявлять глобальные переменные этих классов, типа SERVER server.

Не очень хочется в каждом файле прописывать отдельно все инклюды. Ведь куда проще в одном файле что-то изменить. Как это делается в нормальных проектах?
p.s И всё же хочется почитать про линковщик, ибо такую логику мой мозг понять отказывается
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
29.08.2012, 13:36     Ошибки линковщика #4
в коде есть зависимости. чем их меньше тем лучше.
если класс A ничего не должен знать о классе B, то и не надо инклуд от класса B включать в класс А.
Иначе любые изменения в хидере класса B приведут к перекомпиляции кода для класса A. Если бы вы большой проект организовали таким же образом, то его сборка занимала бы существенное время. Како-го было бы ждать скажем минут 15 сборки после простой правки кода? А час? А если таких правок много?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
29.08.2012, 13:51     Ошибки линковщика #5
Глобальные переменные в каком файле находятся?
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.08.2012, 14:12  [ТС]     Ошибки линковщика #6
alsav22, уже все нормально. Чуть переписал код и сделал server - указателем. Так проще работать с созданием и удалением сервера (конструктором и деструктором), чем со статической переменной.
Случайно обозвал глобальные переменные, как второй "server.h".
DU, спасибо, учту.
Кстати, мне вот интересно, а есть ли смысл гвардить cpp-файлы? По логике - нет, но вдруг?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
29.08.2012, 14:26     Ошибки линковщика #7
гвардятся инклуды. с сpp файлами нет таких проблем. они в обрабатываемой еденице трансляции встречаются только один раз по определению. translation unit - это сpp файл + все инклуды
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.08.2012, 14:27     Ошибки линковщика
Еще ссылки по теме:

C++ не могу найти ошибку линковщика
C++ Непонятные ошибки линковщика
C++ Призрачная ошибка линковщика

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

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
29.08.2012, 14:27     Ошибки линковщика #8
nexen, .cpp файлы не включаются через #include, потому очевидно нет.
Yandex
Объявления
29.08.2012, 14:27     Ошибки линковщика
Ответ Создать тему
Опции темы

Текущее время: 11:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru