Пространство имен C / C ++ в проблеме заголовка - PullRequest
2 голосов
/ 06 марта 2012

Я пытаюсь реализовать сервер Websocket. Я использую библиотеку libwebsockets .

ConnectionServer.c файл содержит код установки для библиотеки и функции main () (я не вижу ничего важного для публикации здесь.) Этот файл включает 1 файл для полученного обратного вызова данных, который называется: dmserver_callback.cpp. Этот файл затем включает в себя другой файл (мой пользовательский файл анализатора), который называется: data_parser.cpp. Затем этот файл включает файл с именем definitions.h (источник проблемы).

Просто потерпи меня; Я понимаю, что включение файлов (последовательное соединение; так сказать), вероятно, не лучший способ сделать это, и я, скорее всего, должен использовать заголовочные файлы и тому подобное. У меня есть один вопрос: это особенно необходимо?

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

Файл definitions.h выглядит следующим образом:

namespace EngineDefinitions {
enum Version {
    Major = 1,
    Minor = 2
}; //Version;

namespace Server {
    enum enum_Server {
        MAX_PLAYERS = 200,
        MAX_TABLES = 42, // 3 tables per row.
        MAX_TABLE_PLAYERS = 10,
        GAME_PORT = 2040, //2042
        MAX_PARAMS = 10
    }; //Server;
};

namespace Login {
    enum enum_Login {
        USERNAME = 1,
        PASSWORD = 2
    }; //Login;
};
};

Моя ошибка:

definitions.h(1): error C2061: syntax error : identifier 'EngineDefinitions'

Я загрузил точно такой же заголовок в новый консольный проект Win32 в Visual C ++ 2010 Express, и там все работает. Единственное отличие, которое я вижу, это основной файл (где находится основная функция int). В проекте работает заголовочный файл: ConectionServer.cpp (C ++)

и основной файл проекта, который не работает, называется: ConnectionServer.c (С)

Это как-то связано с файлом, компилируемым в C против C ++?

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

P.S. Пожалуйста, дайте мне знать, если есть какая-либо другая информация, которую я могу предоставить, чтобы помочь.

РЕДАКТИРОВАТЬ: Я также понимаю, что вы не должны определять типы внутри файла заголовка (например, enums). Я пытался разделить источник на .cpp и файл заголовка, используя extern enum без разницы. На самом деле, я получил больше ошибок (переопределений), чем я рассчитывал, пытаясь их использовать.

Ответы [ 3 ]

6 голосов
/ 06 марта 2012

Вы должны понимать, что C ++ и C - это разные языки. Когда вы включаете заголовочный файл в файл .cpp, компилятор попытается скомпилировать .h как код C ++. C ++ поддерживает пространства имен, поэтому все довольны. Но когда вы пытаетесь включить .h из файла .c (что на самом деле происходит, если вы следуете за #include), компилятор пытается скомпилировать .h как код C, но не удается, потому что пространства имен в C нет .

Распространенным способом решения этой проблемы является использование предопределенных макросов. __cplusplus определяется при компиляции как код C ++ и не определяется при компиляции как код C (очевидно).

Вы можете сделать это:

#ifdef __cplusplus
namespace EngineDefinitions {
#endif
enum Version {
    Major = 1,
    Minor = 2
}; //Version;

#ifdef __cplusplus
namespace Server {
#endif
    enum enum_Server {
        MAX_PLAYERS = 200,
        MAX_TABLES = 42, // 3 tables per row.
        MAX_TABLE_PLAYERS = 10,
        GAME_PORT = 2040, //2042
        MAX_PARAMS = 10
    }; //Server;
#ifdef __cplusplus
};
#endif

#ifdef __cplusplus
namespace Login {
#endif
    enum enum_Login {
        USERNAME = 1,
        PASSWORD = 2
    }; //Login;
#ifdef __cplusplus
};
#endif

И, конечно, вы теряете способность пространства имен в Си в любом случае.

4 голосов
/ 06 марта 2012

C не имеет пространств имен. Для настоящих.

1 голос
/ 06 марта 2012

Вы не можете включить файл C ++ в файл C (если он не был подготовлен для такого использования). Если вы затем попытаетесь скомпилировать файл C, он попытается скомпилировать даже файл C ++ как C. Вместо этого используйте отдельные файлы компиляции и заголовочные файлы.

Обратите внимание, что C не понимает пространства имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...