2014-07-01 90 views
5

在下面的代碼中,我試圖從C函數中調用用C++編寫的虛擬函數(使用C++頭文件,如ap_fixed.h,ap_int.h)。當我用g ++編譯時,代碼運行良好。但是當我使用gcc編譯test.c時,它會拋出一個錯誤,因爲我已經包含了一個C++頭文件,這是一個有效的錯誤。在C中使用gcc鏈接C++靜態庫

是否有任何解決方法使用gcc進行編譯?我從一些文章中讀到,以這種方式合併C/C++代碼並不是一個好習慣。請指教我是否有任何嚴重的問題與一個大的C代碼庫工作,並做類似的事情。

感謝

頭文件:testcplusplus.h

#include "ap_fixed.h" 
#include "ap_int.h" 

#ifdef __cplusplus 
extern "C" { 
#endif 

void print_cplusplus(); 

#ifdef __cplusplus 
} 
#endif 

testcplusplus.cc

#include <iostream> 
#include "testcplusplus.h" 

void print_cplusplus() { 

ap_ufixed<10, 5,AP_RND_INF,AP_SAT > Var1 = 22.96875; 
std::cout << Var1 << std::endl; 
} 

test.c的

#include <stdio.h> 
#include "testcplusplus.h" 

int main() { 
print_cplusplus(); 
} 

使用的命令:

g++ -c -o testcplusplus.o testcplusplus.cc 
ar rvs libtest.a testcplusplus.o 
gcc -o test test.c -L. -ltest 

錯誤:

In file included from ap_fixed.h:21:0, 
       from testcplusplus.h:1, 
       from test.c:2: 
ap_int.h:21:2: error: #error C++ is required to include this header file 
+1

您可以指定'GCC -x C++' –

+0

不相關的迫在眉睫的問題輸入語言,但你應該包括'testcplusplus。在'testcplusplus.c'(它應該有擴展名'.cc'或'.cpp',以確保它被識別爲C++文件)。 –

+0

另外:如果可執行文件中有C++,'main'應該在C++中。 (雖然我不知道現代實現是否仍然需要這個。) –

回答

3

這裏的問題是,C++頭文件ap_fixed.h包含在C程序test.c中(間接地通過testcplusplus.h)。

解決方法是從testcplusplus.h中刪除頭文件「ap_fixed.h」 和「ap_int.h」,並直接從testcplusplus.cpp中包含它們。 C程序不需要知道這些,只有C++包裝器直接使用它們。

在一個更大的例子中,將testcplusplus.h拆分爲兩個頭文件可能是合適的:一個僅包含您向C環境呈現的外部接口的聲明,另一個包含其餘的聲明 - C++內部需要聲明實施和任何必需的包括。

完成此操作後,仍然會面臨鏈接錯誤,因爲生成的可執行文件將包含對來自C++運行時庫以及您的C++代碼使用的任何其他庫的符號的引用。爲了解決這個問題,編譯最終可執行文件時,如增加-l指令:

gcc -o test test.c -L. -ltest -lstdc++ 
+0

我用你的建議先生,但仍然有一些錯誤。我必須使用-lstdC++選項和gcc才能成功編譯test.c –

+1

好吧,那也是另一個方面:可執行文件需要鏈接到標準的C++庫,否則你會得到未定義的引用。我會將其添加到答案中。 – harmic

1

你並不需要包括ap_int.h在這一點上ap_fixed.h,作爲print_cplusplus函數的聲明並不需要這些定義。

相反,將它們包含在testcplusplus.c中中,所以C編譯器只能看到C++代碼的C兼容接口。