C++程序編譯之謎(二)——隱藏源碼,動態和靜態連接庫的祕密

前面咱們提到了若是咱們不但願把咱們的源碼提供出來,可是又想提供這個接口給調用者調用,那麼這個該怎麼作呢?bash

咱們能夠考慮用靜態連接庫或者動態連接庫。app

一、連接庫

那麼什麼叫連接庫呢?說白了,就是一個二進制文件,是經過特殊方式生成的一個二進制文件,在連接的時候,能夠準確地生成可執行文件。函數

那麼靜態連接庫和動態連接庫有什麼區別呢?spa

靜態連接庫在連接的時候程序會把靜態連接庫中的全部函數插入到你的可執行文件中,在這種連接方式下,函數的代碼將從其所在地靜態連接庫中被拷貝到最終的可執行程序中。Linux平臺通常都是.a結尾的文件,像libadd.a這樣,window平臺通常是.lib結尾的文件,像add.lib這樣。接口

優勢:運行速度比較快源碼

缺點:可執行文件的會比較大it

動態連接並無說把庫文件的代碼插入到可執行文件中,而是在運行的時候連接庫中的函數再加載到可執行文件中,也就是說運行的時候發現調用的函數是在動態庫中,那麼纔去巴拉巴拉的加載。Linux平臺通常都是.so結尾的文件,像libadd.so這樣,window平臺通常是.dll結尾的文件,像add.dll這樣。因此不少時候你在window上安裝軟件,若是你到安裝目錄下查看,可能會看到很dll結尾的文件,而這些就是第三方的動態庫。編譯

優勢:可執行文件的會比較小class

缺點:運行速度比較慢變量

那麼咱們如何生成靜態庫和動態庫,如下生成方法均是在Linux平臺

二、靜態連接庫

生成靜態連接庫

首先生成.o文件

gcc -c add.cpp -o add.o

或者直接這樣也能夠,默認生成的也是.o文件

gcc -c add.cpp

生成靜態連接庫,靜態庫命名的規則lib+名字+.a

ar rcs libadd.a add.o

生成可執行文件

gcc main.c libadd.a -o maina

maina是利用靜態庫生成的可執行文件,這個其實是比較簡單的寫法,是頭文件、源文件、連接庫都在同一目錄的狀況,若是是在不一樣的目錄的話,就要這樣

gcc main.cpp -Iinclude lib/libadd.a -o maina

簡化成公式就是如下這樣

gcc + 源文件 + -I頭文件目錄 + lib/libxxx.a + -o 可執行文件名

以上就是利用靜態連接庫生成可執行文件的方法,比較容易理解。ps:實際上還有另一種方式生成靜態庫的,你知道是什麼嗎?

三、動態連接庫

生成動態連接庫

首先生成與位置無關的.o文件,-fPIC表示與位置無關

gcc -fPIC -c add.cpp -o libadd.o

ps:這邊我也沒法這個與位置無關究竟是什麼個意思,由於我用靜態庫那邊的那個.o文件也能夠生成動態庫。

而後生成動態庫

gcc -shared -o libadd.so libadd.o

組後生成可執行文件

gcc main.cpp libadd.so -o mainso

可是運行可執行文件的時候,可能會報如下錯誤:

./mainso: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory

這個的意思是找不到動態連接庫,解決辦法是修改當前用戶的.bash_profile文件,添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/yourpath,其中yourpath是你動態庫存放的目錄,好比個人是/app/process/alittle,最後執行source .bash_profile讓環境變量生效。這裏要記得必定要另開一個窗口執行,否則仍是會這個錯誤。

以上就是靜態庫和動態庫的內容,涉及到了一些編譯過程的命令,因此後面我會和你們說下程序編譯的相關過程。

更多精彩內容,請關注同名公衆:一點月光(alittle-moon)

相關文章
相關標籤/搜索