看板 C_and_CPP 關於我們 聯絡資訊
仔細看了一下你的敘述我發現了一個很大的問題: InstantAI.h 裡面使用了 using namespace 一般來說 header file 裡不應該宣告全域的 using 敘述 因為這會造成所有引入這個標頭檔的檔案強迫把所 using 的東西給打開 (這有個名詞叫 namespace pollution, 命名空間污染) 在這裡你的 InstantAI.h 裡的宣告污染到了主程式 然後因為 Automation::BDaq 下面大概也有一個 uint8 (全名 Automation::BDaq::uint8) 但 winsock 裡的 uint8 是全域的 (全名 ::uint8) 而它的 macro 也許是展開成不帶 :: 的 uint8 造成編譯器看到不帶 :: 的 uint8 時找到了這兩個候選人 但他不知道你是指誰 (因為 Automation::BDaq::uint8 被 using 打開了) 所以就噴 C2872 沒理解錯的話 InstantAI.h 應該是你自己寫的檔案 這樣的話有兩個方法, 一個治標, 一個治本 治標法是把 InstantAI.h 裡那兩行 using namespace 移到 Datareadfunction() 裡面 這樣那就是函式區塊裡才有 using namespace 的效果 於是函式外面的 uint8 就只看得到 winsock 定的 ::uint8 治本法是你就不要留函式實作在 .h 裡了, 留宣告就好 另外開一個 .cpp 寫 Datareadfunction() using namespace 什麼的也移去那邊 最後編譯完再把兩個檔案連結起來 這樣兩個 .cpp 是各自的編譯單位, 誰都不會影響誰 -- 'Oh, Harry, don't you see?' Hermione breathed. 'If she could have done one thing to make absolutely sure that every single person in this school will read your interview, it was banning it!' ---'Harry Potter and the order of the phoenix', P513 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.195.39.85 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1433700253.A.0AA.html
t78923t: 所以治本的辦法是將副程式改放在.cpp檔裡面 而不放在.h檔 06/08 03:43
t78923t: 然後用主程式(寫在.cpp檔裡)去呼叫改寫在另一個.cpp檔裡 06/08 03:44
t78923t: 的副程式Datareadfunction()? 06/08 03:45
t78923t: 也就是把原本用.cpp呼叫.h檔的方式改成用.cpp呼叫.cpp檔? 06/08 03:46
Killercat: er...聽起來你要include cpp?這是大忌喔 06/08 05:15
linotwo: include 只是單純把程式碼串在一起而已 06/08 10:16
linotwo: 串好的程式碼拿去編譯出來的目的檔就算呼叫未定義的函式 06/08 10:17
linotwo: 編譯也不會有問題 06/08 10:18
linotwo: 因為在連結並產生執行檔的階段,linker會試圖去解決 06/08 10:20
linotwo: 兩個 CPP 檔意味著將會產生兩個目的檔 06/08 10:21
linotwo: 而其中一個檔內的主程式會去呼叫另一個檔內的副程式 06/08 10:23
anyoiuo: global, namespace都有相同的typdef應該不會有問題才對 06/08 11:16
anyoiuo: http://ideone.com/Oze0ZM 像這樣也都不會有錯誤 06/08 11:17
anyoiuo: 出現Ambiguous比較像Killercat提到的相同名稱有不同定義 06/08 11:21
anyoiuo: 像http://ideone.com/RSRQFd,此時只須明確定義要使用哪 06/08 11:23
anyoiuo: 個namespace底下的uint8即可(XXXX::uint8 ...)。 06/08 11:24
anyoiuo: 應該盡量避免將副程式寫在header檔裡,用前面說的header+ 06/08 11:29
anyoiuo: cpp,h檔宣告prototype,cpp進行實作後linker會幫你處理。 06/08 11:31
t78923t: 各位指的意思是 兩個.cpp檔不須互相include 只需要在專案 06/08 12:08
t78923t: 各位指的意思是 兩個.cpp檔不須互相include 只需要在專案 06/08 12:15
t78923t: 設定裡設定Linker副程式 然後主程式加上Datareadfunction 06/08 12:16
t78923t: () 就好了嗎? 06/08 12:16
anyoiuo: 假設你main要使用void func(int a), 這時有三個檔案 06/08 13:09
anyoiuo: main.cpp xxx.h xxx.cpp, main include xxx.h 06/08 13:09
anyoiuo: xxx.h寫function protype, void func(int a); 06/08 13:10
anyoiuo: xxx.cpp對func進行實作, void func(int a) { //todo } 06/08 13:11
anyoiuo: 但Ambious symbol問題還是可能存在,記得當type在不同 06/08 13:14
anyoiuo: namespace下都有定義且定義為不同的對象時,要明確指定你 06/08 13:15
anyoiuo: 要使用哪個namespace下的,ex.Automation::BDaq::uint8 x 06/08 13:17
anyoiuo: 不然編譯器看到他是A同時又是B會不知怎辦。 06/08 13:20
基本上正常來說 anyoiuo 提的方式才是使用 namespace 下的符號的正道 只是這裡不巧的是用它的人是 winsock 的 macro (大概就是 MAKEWORD) 那個 header 沒有考慮到 namespace 的問題 (或者根本就是 C header) 因此才必須要倒過來使用避免 namespace pollution 的方式把東西分開 ※ 編輯: LPH66 (140.112.30.32), 06/08/2015 15:51:11
anyoiuo: 話說那行MACRO在windef.h 06/08 16:51
anyoiuo: 長這樣((WORD)(((BYTE)(a))|(((WORD)((BYTE)(b)))<<8))) 06/08 16:52
anyoiuo: 所以你拆開測ok嗎? 06/08 18:00
t78923t: anyoiuo大的方法看的不是很懂...進行實作的意思指的是編 06/09 22:22
t78923t: 譯(build)? 06/09 22:23
LPH66: 關鍵字: 多檔編譯, 再加上你所用的 IDE 下去 google 06/10 01:19