[root@ ~/learn_code/C++_learn]$ tree.├── main├── main.cpp├── test│ ├── libtest.a│ ├── makefile│ ├── test.c│ ├── test.h│ ├── test.i│ ├── test.o│ └── te ...
//1,編譯靜態庫 libtest.a gcc -c test.c -o test.o ar rc libtest.a test.o //2,編譯main函數 g++ -o main main.cpp -I./test -L./test -static -ltest
test相關文件放在了當前的test目錄下
[root@ ~/learn_code/C++_learn]$ tree
.
├── main
├── main.cpp
├── test
│ ├── libtest.a
│ ├── makefile
│ ├── test.c
│ ├── test.h
│ ├── test.i
│ ├── test.o
│ └── test.s
├── test.c
└── test.h
[root@ ~/learn_code/C++_learn/test]$ make libtest.a -B
gcc -c test.c -o test.o
ar rc libtest.a test.o
1,可行
2,更可以,推薦用這種方式
對於比較老的C庫,可能當時寫的沒有考慮到聲明extern 3,可行,推薦使用
4,下麵這種方式報錯
解釋下原因:根本原因是因為編譯器在編譯C++和C文件中的函數時,是區別對待的,也就是說同一個函數名,在C++和C文件中編譯出來的名字不一樣。
比如說對於mytest函數,對於C編譯後為_mytest,對於C++編譯之後名字為_mytest_。下麵解析下上面的幾種情況 對於第1中情況: C++文件include了test.h, 展開了其中的__cplusplus巨集,所以對應 extern "C" void mytest(),編譯後為:_mytest C語法是不支持extern "C"的,當然這裡也不會展開__cplusplus巨集,所以對應 void mytest(),編譯後為:_mytest 對於第2中情況: 更不用說了,同第1中情況 對於第3中情況: 對於以前寫的C庫,可能大多數時候都是這種寫法 這個時候就得在包含它的C++文件中,必須顯式的聲明 extern "C"關鍵字。 對於第4種情況: C++文件include了test.h,對應 void mytest(),編譯後為:_mytest_ (註意與第一種情況的區別) C語法是不支持extern "C"的,當然這裡也不會展開__cplusplus巨集,所以對應 void mytest(),編譯後為:_mytest 所以這裡在生成main的可執行文件的時候會鏈接錯誤。1 [root@ ~/learn_code/C++_learn]$ g++ -o main main.cpp -I./test -L./test -static -ltest 2 /tmp/cc3TGBKW.o: In function `main': 3 main.cpp:(.text+0x5): undefined reference to `mytest()' 4 collect2: ld returned 1 exit status
結論:
1,在寫C函數庫的時候,儘量帶上巨集__cplusplus這一段聲明,方便後面使用 2,在寫C++程式的時候,加入會調用C庫,儘量帶上巨集__cplusplus這一段聲明,肯定就不會報相關編譯的錯誤了。