2012-03-06 43 views
2

我試圖實現一個WebSocket服務器。我正在使用libwebsockets庫。標題問題中的C/C++名稱空間

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 main函數駐留)。 在該頭文件中的作品被稱爲項目: ConectionServer.cpp(C++)

和不工作被命名爲主要的項目文件: ConnectionServer.c(C)

這是否有東西做該文件正在編譯C或C++?

我認爲libwebsocket庫是用C編碼的。 我不記得我是否以完全相同的方式創建了項目文件。

P.S.請讓我知道是否有任何其他信息可以提供幫助。

編輯:我也意識到你不應該定義頭文件內的類型(例如:枚舉)。 我嘗試使用extern enum 將源文件分成.cpp和頭文件,沒有區別。事實上,當我嘗試使用它們時,出現了比我討價還價更多的錯誤(重新定義)。

+0

你真的不應該包含'.cpp'文件。 – Marlon 2012-03-06 04:52:43

+0

是的,我明白我不應該以這種方式包含文件。正如我所提到的,即使我使用適當的頭文件,我仍然在第一個項目中得到這個錯誤,但不是第二個。 – 2012-03-06 04:57:01

+1

您需要了解C++和C是不同的語言。將頭文件包含在'.cpp'文件中時,編譯器會嘗試將'.h'編譯爲C++代碼。 C++支持命名空間,所以每個人都很開心。但是當你嘗試從'.c'文件中包含'.h'(這是實際發生的事情,如果你遵循'#include's),編譯器試圖將'.h'編譯爲C代碼,但因C中不存在名稱空間而失敗。沒有人開心。 – Marlon 2012-03-06 04:59:16

回答

5

您需要了解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 

,當然還有,你失去的命名空間的能力,用C反正。

+2

如果你這樣做,你需要額外的超級小心處理命名衝突。在編譯代碼時,在根名稱空間中放入類似'Version'或'Major'的東西可能不是一個好計劃。 – 2012-03-06 05:06:05

+0

這是迄今爲止最好的答案,所以我將其標記爲如此。我的問題的最佳解決方案是將項目轉換爲C++。另外,作爲說明,我明白他們是不同的語言,但無法知道項目設置爲什麼,因爲這兩個項目都是用Visual C++打開的。我假設這是我的問題 - 對不起,如果我沒有這樣做明顯。 – 2012-03-06 05:15:19

+0

更新:我剛完成將項目更新到C++,現在一切都按照預期工作。你幾乎發現它在做什麼。當命名空間需要C++時,編譯器試圖將程序編譯爲C.感謝幫助。 – 2012-03-06 05:39:13

4

C沒有名稱空間。真的。

1

您不能在C文件中包含C++文件(除非它已準備好用於此類用途)。如果您嘗試編譯C文件,它會嘗試將C++文件編譯爲C,而不是使用單獨的編譯和頭文件。

請注意,C不理解命名空間。

+0

@Levi:聽起來好像是時候拿起[一本關於C++編程的好書](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 – 2012-03-06 05:03:12