天天看點

靜态庫之間的依賴問題

作者:小莊讀書

最近一次偶然的機會,發現了C語言靜态庫之間一個依賴問題,事情是這樣的……

主程式調用靜态庫A中的一個函數如‘test1()’,靜态庫A中的這個函數‘test1()’調用了另一個靜态庫B裡面的一個沒有入參的函數‘test2()’。後來靜态庫B裡面的函數‘test2()’增加了入參,但是靜态庫A沒有一起重新編譯生成,但是使用了這兩個靜态庫的主程式重新編譯執行都沒有問題。

經過一系列分析,總結下來原因應該是這樣的:

1、主程式在連結兩個庫的時候,靜态庫A的函數‘test1()’調用的函數‘test2()’在靜态庫B中可以找得到,因為C語言不支援函數重載,是以帶參數和不帶參數的函數符号在庫裡面是一樣,是以可以連結成功。

2、主程式執行過程中,當執行到函數‘test2()’的時候,函數入參直接是從相應的寄存器中讀取的,是以盡管調用函數‘test2()’的時候沒有傳參,但函數從寄存器中可以讀取到預設值,仍能夠正确執行。

//靜态庫A
#include "slib1.h"
#include "slib2.h"

void test1() {
    test2();
    //test2(33);
}

//靜态庫B
#include "slib2.h"

void test2() {
//void test2(int x) {
}           

編譯生成靜态庫後,靜态庫A中顯示函數‘test2’未定義:

靜态庫之間的依賴問題

靜态庫B的函數‘test2()’加了入參,重新編譯生成後,從彙編可以看出,函數的參數是從寄存器擷取的:

靜态庫之間的依賴問題

下面兩個截圖,則分别是靜态庫A調用函數‘test2()’不傳參和傳參的彙編,可以看出來兩者的差别就是傳參調用多了一步,把參數放入寄存器中。

靜态庫之間的依賴問題

不傳參調用函數

靜态庫之間的依賴問題

傳參調用函數

綜上,靜态庫調用的外部函數也并不是把全部代碼都直接放到庫裡面的,是以如果靜态庫之間存在依賴關系的話,在寫Makefile的時候,一定要當心、處理好這些依賴關系~~

靜态庫之間的依賴問題

繼續閱讀