前面我們提到了如果我們不希望把我們的源碼提供出來,但是又想提供這個接口給調(diào)用者調(diào)用,那么這個該怎么做呢?
我們可以考慮用靜態(tài)鏈接庫或者動態(tài)鏈接庫。
那么什么叫鏈接庫呢?說白了,就是一個二進制文件,是通過特殊方式生成的一個二進制文件,在鏈接的時候,可以準確地生成可執(zhí)行文件。
那么靜態(tài)鏈接庫和動態(tài)鏈接庫有什么區(qū)別呢?
靜態(tài)鏈接庫在鏈接的時候程序會把靜態(tài)鏈接庫中的所有函數(shù)插入到你的可執(zhí)行文件中,在這種鏈接方式下,函數(shù)的代碼將從其所在地靜態(tài)鏈接庫中被拷貝到最終的可執(zhí)行程序中。Linux平臺一般都是.a結尾的文件,像libadd.a這樣,window平臺一般是.lib結尾的文件,像add.lib這樣。
優(yōu)點:運行速度比較快
缺點:可執(zhí)行文件的會比較大
動態(tài)鏈接并沒有說把庫文件的代碼插入到可執(zhí)行文件中,而是在運行的時候鏈接庫中的函數(shù)再加載到可執(zhí)行文件中,也就是說運行的時候發(fā)現(xiàn)調(diào)用的函數(shù)是在動態(tài)庫中,那么才去巴拉巴拉的加載。Linux平臺一般都是.so結尾的文件,像libadd.so這樣,window平臺一般是.dll結尾的文件,像add.dll這樣。所以很多時候你在window上安裝軟件,如果你到安裝目錄下查看,可能會看到很dll結尾的文件,而這些就是第三方的動態(tài)庫。
優(yōu)點:可執(zhí)行文件的會比較小
缺點:運行速度比較慢
那么我們?nèi)绾紊伸o態(tài)庫和動態(tài)庫,以下生成方法均是在Linux平臺。
生成靜態(tài)鏈接庫
首先生成.o文件
gcc -c add.cpp -o add.o
或者直接這樣也可以,默認生成的也是.o文件
gcc -c add.cpp
生成靜態(tài)鏈接庫,靜態(tài)庫命名的規(guī)則lib+名字+.a
ar rcs libadd.a add.o
生成可執(zhí)行文件
gcc main.c libadd.a -o maina
maina是利用靜態(tài)庫生成的可執(zhí)行文件,這個實際上是比較簡單的寫法,是頭文件、源文件、鏈接庫都在同一目錄的情況,如果是在不同的目錄的話,就要這樣
gcc main.cpp -Iinclude lib/libadd.a -o maina
簡化成公式就是以下這樣
gcc + 源文件 + -I頭文件目錄 + lib/libxxx.a + -o 可執(zhí)行文件名
以上就是利用靜態(tài)鏈接庫生成可執(zhí)行文件的方法,比較容易理解。ps:實際上還有另外一種方式生成靜態(tài)庫的,你知道是什么嗎?
生成動態(tài)鏈接庫
首先生成與位置無關的.o文件,-fPIC表示與位置無關
gcc -fPIC -c add.cpp -o libadd.o
ps:這邊我也無法這個與位置無關到底是什么個意思,因為我用靜態(tài)庫那邊的那個.o文件也可以生成動態(tài)庫。
然后生成動態(tài)庫
gcc -shared -o libadd.so libadd.o
組后生成可執(zhí)行文件
gcc main.cpp libadd.so -o mainso
但是運行可執(zhí)行文件的時候,可能會報以下錯誤:
./mainso: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
這個的意思是找不到動態(tài)鏈接庫,解決辦法是修改當前用戶的.bash_profile文件,添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/yourpath,其中yourpath是你動態(tài)庫存放的目錄,比如我的是/app/process/alittle,最后執(zhí)行source .bash_profile讓環(huán)境變量生效。這里要記得一定要另開一個窗口執(zhí)行,不然還是會這個錯誤。
以上就是靜態(tài)庫和動態(tài)庫的內(nèi)容,涉及到了一些編譯過程的命令,所以后面我會和大家說下程序編譯的相關過程。
聯(lián)系客服