2010-02-15 109 views
1

這是如何在C或C++中工作的?使用extern將文件包含在C或C++中

extern "C" { 
#include <unistd.h> 
#include <fd_config.h> 
#include <ut_trace.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
} 
+5

它不應該在C中工作。'extern「C」'是C++的東西;它告訴編譯器將後面的任何內容視爲C,以避免名稱混亂。 – GManNickG 2010-02-15 06:47:59

+1

此代碼用於C++。你想知道這個代碼是如何編譯的gcc? – 2010-02-15 06:49:37

+0

是的我想知道它是如何工作在C++ – 2010-02-15 07:06:21

回答

1

它不會工作,你需要添加CPLUSPLUS預處理...

#ifdef __cplusplus 
extern "C" { 
#endif 

// your code 


#ifdef __cplusplus 
} 
#endif 

編輯:

在C++中,名稱將像C處理也即是說將沒有破爛的名字。它允許使用不同參數類型/編號的兩個C++不同函數或庫中不同的名稱空間(用於庫目的libname.so,libname.a)。如果名稱是錯位,C程序將無法識別它

eg: 
int myfction() 
void myfunction(int) 
void myfunction(int, char) 

C library: myfction 

C++ library: int_myction (it depend on your compiler) 
C++ library: int_myction_int (it depend on your compiler) 
C++ library: int_myction_int_char (it depend on your compiler) 
// ... which is not allowed in C program 
5

C++標準沒有指定編譯器應該如何命名他們的目標文件的符號(例如,Foo::bar()可能最終爲__clsFoo_fncBar或一些gobbledygook)。 C標準確實如此,它幾乎總是與C++編譯器的工作方式不同(C不必處理類,名稱空間,重載等)。因此,在鏈接到由C編譯器輸出的目標文件時,必須告訴C++編譯器查找名稱與C標準相對應的符號。你基本上把它放在「C模式」中。這就是extern "C""C"部分所做的。

(或者,你也可能宣稱可以通過一個外部的C對象文件中使用函數或變量。在這種情況下,這意味着導出這些符號的C方式。)

0

每個C++編譯器需要支持外部「C」連接。 此塊中的代碼可能是用C編寫的遺留代碼,用於某個功能,這是當前程序所需的。

這是如何實現的主要依賴於編譯器,但是我聽說許多編譯器禁用名稱修改並更改調用約定。

2

如果你的項目有C和C++源文件,並且你需要作爲一個整體來構建(C文件在C++文件中調用一些函數),所以我們需要通過在C++文件中聲明來保護C文件函數調用和符號通過

的extern 「C」 {在C文件中使用/ UINT8 GetCurrentthreadState(HANDLE的ThreadId) /符號

}

然後,C++編譯器生成彙編輸出其與上面聲明的函數和符號的C編譯器相同。因此,在鏈接時間上,編譯器可以輕鬆鏈接C和C++定義的符號而不會出現任何鏈接錯誤。

所以我的意見是不需要給#ifdef __cplusplus檢查編譯。 因爲我們需要保護C++文件中的符號嗎?此外,C++文件只能由C++編譯器編譯?

/renjith g

+1

#ifdef __cplusplus警衛是有用的,如果你有一個頭文件中的聲明可能被C和C++程序包含在內。當你有一個混合的C/C++項目或者你正在編寫一個庫時,經常會發生這種情況。 – 2010-02-15 14:21:08

+0

不,如果您使用的是本機C++編譯器,則無需在頭文件中檢查#ifdef __cplusplus宏。對於相同的外部「C」{}用法已足夠。 /renjith g – 2010-02-15 18:33:52