天天看点

静态库之间的依赖问题

作者:小庄读书

最近一次偶然的机会,发现了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的时候,一定要当心、处理好这些依赖关系~~

静态库之间的依赖问题

继续阅读