C與C 在Linux下的混合編譯問題zz

2021-04-13 05:18:45 字數 1805 閱讀 1392

最近遇到乙個挺撓頭的技術問題,我們波士頓那邊客戶公司的**是既有c++又有c,我們作為外包公司,需要把我們的c++**與他們的整合起 來,原先的整合方案是我們的c++與他們的c++揉在一起,這樣不touch任何c整合的冬冬,我當時在波士頓已經搞定了此問題,但出差回來前客戶提出要 優化系統效率,其意思就是想讓我們更多地重用他們的c**,這樣整合c與c++的任務逐漸提上日程。

,文章有四個部分,

前三個部分屬於科普,可以不看,最後乙個部分講述了c++呼叫c和c呼叫c++的兩個範例,甚是有用,我總結一下:

(1)c++呼叫c的問題:

在c++的file中,加入c的標頭檔案,一般情況下需要加extern "c", 但這點不是鐵律,後面我會專門講這個問題,認定這點有時會死得比較慘。建議原文範例中增加__cplusplus巨集比較好一些,例如:

#if defined(__cplusplus)

extern "c"

#endif

加extern "c"的原因是因為c++在編譯函式名時加入了很多其他怪異字元,這點是c++語言為了支援過載overload的特性以及其它特性所不得不加的冬冬,但 c是樸素型,編譯出來的符號表就是**裡的函式名。加了extern c後,編譯器就會按照c的命名方式將c++引用c**的地方使用c方式的函式名,避免引用和定義出現命名的不一致。但有乙個問題是這一點取決於特定的編譯 器,而不是絕對的,我在.net的vc7下拿我們的工程做了個試驗沒有問題,但在linux的g++下就歇了,原因是什麼?window下的nmake在 編譯時使用的原則是:c**按照c的命名方式編譯引用點和函式定義,可是g++就是另外一回事了,它對c的**採取的是c++的命名方式,怎麼印證這個問 題呢,下面我來介紹一下linux

下的兩個工具nm和objdump, 命令如下:

objdump -x (obj檔名) , nm (obj檔名)

下面給出更詳盡的測試依據,例如c**中的pp__sctp函式在g++編譯後的符號表就變了,

nm mylib.a |grep pp__sctp

結果是:

u _z8pp__sctppkcmm

000000c0 b v__pp__sctp

00000040 t _z8pp__sctppkcmm

看到了吧!u是引用點的函式符號,t的定義點的函式符號,如果你在呼叫時加了extern "c",編譯後,肯定會有一條錯誤說:undefined reference "pp__sctp".

這就是我要講的第乙個問題,c,c++整合編譯時需要看具體的編譯環境和工具,充分利用你手頭的工具幫你來分析和定位問題。

(2) c調c++的問題,具體可以參看前面說的文章,非常有用,要點是:c呼叫c++,通過extern 變數或函式的外部宣告,而不用include標頭檔案方式。但前面提到的第乙個問題依然會在不同的編譯器下重演,你需要定位分析,看是否需要加extern "c",只要耐心一些,就會快速定位和解決問題。

我這裡提到的第二個問題是在複雜工程下會出現的問題,我 們的工程巨大,六千多個檔案,和我們相關的就有7,8百個,最後在鏈結時,出了問題是幾個靜態庫互相引用,打成了死結,因為g++ 通過-l選項加入庫的順序也是有講究的,先引用的庫可以使用後引用庫的函式和變數,但反過來則不行。

這裡介紹乙個辦法,利用拓撲分析,把幾個庫的引用關係用圈和箭頭表示出來,就像分析最短路徑那樣,如果發現是個環狀拓撲,只管把它們加入到乙個庫中即可,當然這是在linux下,windows下我不sure是否會出現類似問題。

昨天晚上在家裡用vpn連到單位忙到12點才搞定,白天也多虧幾位同事的幫助才有了思路,呵呵,解決了問題就是爽啊!

c與c 的混合編譯

記錄一次意外經歷 在c 函式中使用c 在函式前加上extern c 來註明 extern c 的主要作用就是為了能夠正確實現c 呼叫其他c語言 加上extern c 後,會指示編譯器這部分 按c語言的進行編譯,而不是c 的。由於c 支援函式過載,因此編譯器編譯函式的過程中會將函式的引數型別也加到編譯...

C與C 混合程式設計 編譯

1.工程檔案架構 drwxrwxr x 3 joshyoby joshyoby 4096 2月 25 15 03 drwxrwxr x 8 joshyoby joshyoby 4096 2月 25 14 45 rw rw r 1 joshyoby joshyoby 671 2月 25 14 58 m...

C 和 C 混合編譯簡述

一 extern c 的作用 最重點 1.extern c 的真實目的是實現類c和c 的混合程式設計。extern c 是由 提供的乙個連線交換指定符號,用於告訴 這段 是 函式。extern c 後面的函式不使用的c 的名字修飾,而是用c。這是因為c 編譯後庫中函式名會變得很長,與c生成的不一致,...