c調用c++動態庫的實現和注意事項(linux g++)

碼工聲明:本人也在學習,下面有些話是網上摘抄的---吐血的CSDN,圖片不支持拷貝,不支持拷貝爲啥還要正常顯示,導致很多貼圖都沒有了

只介紹c調用c++過程中我所遇到的一些低級錯誤

1.先介紹一下c和c++編譯

如果是已經用c++編譯器編譯好的so文件,使用c語言直接引用是會報錯的,原因是c和c++的編譯器在處理函數名稱時規則不同,相同的函數比如hello(int i),c語言可能會處理成hello或者_hello,具體估計與編譯器有關,但c++的話由於存在重載功能,會將參數類型等信息全部包含進去,一遍唯一定位某一函數,所以c++可能命名爲_Z10helloP9int,這樣即使存在hello函數名稱相同的,但由於參數部分的名字不同,也可以唯一定位到需要的函數。呵呵,c++我不懂,班門弄斧了,囉嗦了一句。

hello.cpp編譯生成libhello.so


相同的函數下面是用c++編譯的結果

“圖片被CSDN吃了”

下面是通過extern "C" 選項編譯的,代碼如圖所示

“圖片被CSDN吃了”

hello.h代碼

“圖片被CSDN吃了”

同樣hello.h中的聲明也要用extern "C",否則會報錯,錯誤如下,應該是相同函數定義規則不同衝突了

“圖片被CSDN吃了”

編譯過後的nm查看函數名如下

“圖片被CSDN吃了”

可以看出函數hello與代碼名稱相同,且不帶參數

2、extern "C",注意c一定要大寫,小寫會報錯;__cplusplus 前面是兩個下劃線

"C"表示的是一種鏈接約定,只是因C和C++語言之間的密切關係而在它們之間更多的應用而已。實際上Fortran和彙編語言也常常使用,因爲它們也正好符合C實現的約定。
extern "C"指令描述的是一種鏈接約定,它並不影響調用函數的定義,即時做了該聲明,對函數類型的檢查和參數轉換仍要遵循C++的標準,而不是C

此外還有extern "FORTRAN"

還是以hello word爲例,假設用cpp且不加extern "C"來編譯,那麼生成的libhello.so是按照c++的約定進行編譯的,如果c要調用則必須使用一箇中間的過度,使得編譯生成的函數按照c語言的約定編譯,這樣在調用時才能找到

中間文件定義爲helloInf.cpp,不截圖了,手敲吧

#include "hello.h"

#ifdef   __cplusplus

   extern "C" {

#endif

void helloInf()

{

   hello(1);

#ifdef __cplusplus

   }

#endif

同理如果helloInf.h裏面的聲明也要加上#ifdef __cplusplus.....

編譯生成的libhelloInf.so,用main.c就可以直接調用了

main.c

#include "helloInf"

void main(void)

{

helloInf();

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章