2012-10-30 82 views
0

我有一個代碼,其中我#include<linux/videodev2.h>。有三個文件:在包含頭文件中的差異.cpp和.h

  1. 一個頭文件 - 包括:stdint.hstdlib.h。定義了幾個函數,一個struct,比如說abc和一些#define宏。其中一個功能是一個有很多方法,包括在.h文件的功能定義

    int func(int, uint32_t, size_t, abc*); 
    
  2. 一個CPP文件。

  3. 一個main.cpp,它有main()函數調用.h文件中的方法(下面的完整文件)。此文件僅用於測試目的。

    #include "head.h" 
    int main() { 
        func(5, (uint32_t)5, (size_t)5, 0); 
        return 0; 
    } 
    

什麼是看到的是一個奇怪的情況:

  1. 如果我有linux/videodev2.h只在.h文件中,uint32_t並在此頭文件中定義其他的事情不能由.cpp文件訪問。 (我得到的錯誤是:uint32_t was not declared in this scopeuint32_t does not name a type等等)。即使.h文件的第一行是#include<linux/videodev2.h>
  2. 如果我在兩個cpp文件中都包含videodev2頭文件,那麼它的工作原理只有如果我在.h文件之前導入它(videodev2)。
  3. 如果在main.cpp文件中使用func(5, (uint32_t)5, (size_t)5, (abc*)0);,我得到的錯誤是abc未在此範圍內聲明。

我使用的命令編譯:g++ main.cpp head.cpp

我無法弄清楚這是爲什麼。我想在.h文件中包含videodev2頭文件,因爲幾乎可以確定使用.h文件的代碼將依賴於它。但似乎將它包含在.h文件中根本沒有任何作用。

我在這裏必須誠實。這是我必須轉換爲C++的C代碼。我知道我不符合最佳做法和標準。但爲什麼會出現這種行爲?

+0

我不知道它是什麼,但我把這三個文件移動到一個新的目錄。它完美地編譯。舊目錄中有很多文件。你們有沒有任何建議,爲什麼其他文件的存在會影響到這一點? – Deepanshu

回答

0

找到了答案。目錄中有.h.gch文件。我不知道預編譯頭文件。感謝ktodisco的洞察力。我仍然不知道爲什麼那個文件在那裏。

3

請記住,#include指令向預處理程序指示應該將指定文件的內容視爲直接出現在源文件中而不是指令(解釋自MSDN)。

考慮到這一點,您似乎遇到#include s的錯誤訂單,也錯過了#include s。我的猜測是你沒有在你的.cpp文件中包含你自己的頭文件。這將解釋案例一和三。考慮以下文件:

// header.h 
// #include <linux/videodev2.h> <-- Option 1 
class A { 
    void func(uint32_t var); 
}; 

// header.cpp 
void A::func(uint32_t var) { 
    // implementation 
} 

// main.cpp 
// #include <linux/videodev2.h> <-- Option 2 
#include "header.h" 
// #include <linux/videodev2.h> <-- Option 3 

int main() { 
    // implementation; something creates an instance of A and calls func 
} 

現在,選項1是not exactly desirable;在頭文件中避免使用#include是個好習慣,因爲它們會增加構建時間並創建不需要的依賴關係。但是,它將確保header.h需要的類型供它使用。必要的是的內容linux/videodev2.h必須出現在header.h的內容之前,任何地方header.h#include d。

這將我帶到選項2.選項2也將正確編譯,因爲linux/videodev2.h包含在您的標題之前,並且您的標題依賴於其中定義的類型。同樣重要的是main.cppheader.cpp必須爲#include "header.h",因爲它們在其中聲明瞭參考符號。

如果您選擇使用選項3,則會出現編譯錯誤,其類型uint32_t未定義,編譯器將指向您的頭文件。這是因爲頭文件的內容出現在linux/videodev2.h的內容之前,所以編譯器還不知道什麼類型uint32_t遇到它時。因此,你可以選擇:在包含你自己的頭文件之前加入`linux/videodev2.h',或者直接將它包含在你的頭文件中。我之前提到過後者不是好的做法,但對於您的特殊情況,如果您的頭文件需要包含在許多.cpps中,它可能是兩者中更好的選擇。

我認爲這將是潛入precompiled headers的好機會,但我不太瞭解他們,所以我會留給有更多經驗的人解釋他們。

希望這會有所幫助:)

+1

感謝您的詳細回覆。真的很感激它。但我認爲只是將這三個文件移動到一個乾淨的目錄中工作。是否有一些原因,爲什麼舊​​目錄中的其他文件會導致此問題? – Deepanshu

相關問題