linux下c c 混合程式設計

2021-06-25 20:13:43 字數 3184 閱讀 9972

一. 知識儲備:

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 編譯後庫中函式名會...