一. 知識儲備:
linux下c++用的編譯器是g++,而編譯c程式中用的編譯器是gcc,編譯出來的obj檔案肯定是不一樣的,但是c++是相容c的,所以c++檔案是可以編譯成相容c的**,比如
#include using namespace std;
void test()
1.cpp編譯成.o檔案==> g++ -c 1.cpp
nm 1.o
u __cxa_atexit
u __dso_handle
00000044 t _global__sub_i__z4testv
00000005 t _z41__static_initialization_and_destruction_0ii
00000000 t _z4testv //這裡 test函式經過g++編譯之後(沒鏈結之前),將函式test進行了修飾,即 test前面加上了_z4,後面加上v(即void 引數),若test函式中的引數是int型變數,則編譯之後應該為 _z4testi(i為int行)
u _znst8ios_base4initc1ev
u _znst8ios_base4initd1ev
那麼如果是.c檔案編譯成.o檔案會如何呢?
#include
void test()
1.c編譯成.o檔案==> gcc -c 1.c
nm 1.o
00000000 t test //這裡直接就用函式名
通過上面我們可以看出原來c++的函式的過載實質就是這樣啊,編譯器偷偷的將函式名進行了修飾。。。。
那麼c++如何才能編譯成c的那樣的函式名呢?====> 即用 extern "c"
#include
using namespace std;
extern "c" //修飾 test,告訴編譯器編譯的時候以c編譯器的編譯規則來編譯
void test()
之後 g++ -c 1.cpp
nm 1.o
u __cxa_atexit
u __dso_handle
00000044 t _global__sub_i_test
00000000 t test //發現編譯之後只是test函式
00000005 t _z41__static_initialization_and_destruction_0ii
u _znst8ios_base4initc1ev
u _znst8ios_base4initd1ev
00000000 b _zstl8__ioinit
一. c++提供介面給c程式用:
#include using namespace std;
class func
#include "func.h"
int func::add(int num1, int num2) //這裡前面不需要加extern "c",因為func::add 這種寫法無法編譯成c形勢的,因為他本來就是c++的寫法,
介紹三種方法: ①.直接鏈結使用, ②.動態庫, ③.靜態庫
呼叫介面的**:
#include
extern int inte***ce(int num1, int num2);
int main()
①直接鏈結使用:
g++ -c func.cpp
g++ -c inte***ce.cpp
gcc -c main.c
之後都變成了 .o檔案,所以在連線的時候 main函式就會鏈結到inte***ce符號,即可以鏈結上了,而inte***ce中**之後的add_class都是c++形勢編譯的,所以能鏈結上
func, 而func中呼叫c++中的庫cout等等,所以要鏈結 -lstdc++這個動態庫
gcc -o main func.o inte***ce.o main.o -lstdc++
②.動態庫
g++ -fpic -c inte***ce.cpp
g++ -fpic -c func.cpp
g++ -shared -o libadd.so inte***ce.o func.o (-lstdc++) //其實這裡g++自動進行了動態庫stdc++動態庫的鏈結操作,動態庫建立完後可檢視動態庫鏈結資訊,命令是readelf -d libadd.so
標記 型別 名稱/值
0x00000001 (needed) 共享庫:[libstdc++.so.6]
0x00000001 (needed) 共享庫:[libgcc_s.so.1]
0x00000001 (needed) 共享庫:[libc.so.6]
我們在檢視一下內部的介面資訊: nm libadd.so
000007eb t inte***ce //發現有我們呼叫的介面資訊
之後: gcc -o main main.c -l. libadd.so
注意這個是鏈結階段,還有執行階段,我比較懶,就 cp libadd.so /lib/
③.靜態庫
g++ -c inte***ce.cpp
g++ -c func.cpp
ar rv libadd.a inte***ce.o func.o
gcc -o main main.c libadd.a -lstdc++ //注意要加上 -lstdc++,靜態庫只是把兩個.o弄在一起,並且這裡鏈結階段如同第一種方法,cout需要庫,所以要加上-lstdc++,而動態庫的方法就不需要,因為g++生成的動態庫編譯器預設就鏈結上了stdc++這個庫
二. c提供介面給c程式用:
其實很簡單,與上面是一樣得,在c++檔案中extern c程式的界面前加上extern "c"
C C 混合程式設計
c中呼叫c c 中呼叫c都會用到extern c 但兩者的意義卻大不一樣!例 c void foo int x c c code extern c void foo int x 讓c 聯結器能通過過類似於 foo來查詢此函式,而非類似於 foo int這樣的符號。使用extern c 則是告訴編譯器...
C C 混合程式設計
分類 linux c c 2012 12 26 09 51 655人閱讀收藏 舉報cc 混合程式設計 externc cplusplus 現在,我們就來慢慢的了解吧。一 extern c 的作用 最重點 1.extern c 的真實目的是實現類c和c 的混合程式設計。extern c 是由 提供的乙...
C C 混合程式設計
現在,我們就來慢慢的了解吧。一 extern c 的作用 最重點 1.extern c 的真實目的是實現類c和c 的混合程式設計。extern c 是由 提供的乙個連線交換指定符號,用於告訴 這段 是 函式。extern c 後面的函式不使用的c 的名字修飾,而是用c。這是因為c 編譯後庫中函式名會...