有些特殊使用场景,不免会遇到要编译一个程序会同时链接动态库和静态库。同时链接动态库、静态库时,严格限制链接顺序,否则会现各种问题。下面简单总结几点
如下:libfunca.so中调用的func函数,在静态库libfuncb.a和动态库libfuncc.so、动态库libfuncd.so中均有定义。
(1)funca引用静态库funcb中的函数,需要将静态库funcb链接于funca右侧
编译顺序是从左往右加载,当编译funca时发现func未定义,会将其加入未定义符号列表,待加载静态库funcb时将func从未定义符号列表移除。
若静态库funcb置于funca左侧,则func接口始终存于未定义符号列表中,直至编译结束
(2)动态库编译链接,是将动态库中符号重定位到内存,程序只需要在重定位内存找到相应符合就不会报函数未定义。
但是不同动态库定义了相同函数。则按从左到右顺序优先加载左侧函数库中函数(先链接的动态库,重定位后符号靠前)
附代码:
/* main.c */
#include <stdio.h>
int funca();
int main()
{
funca();
return;
}
/* funca.c */
#include <stdio.h>
int funca()
{
printf("AAA\n");
func();
return 0;
}
/* funcb.c */
#include <stdio.h>
int func()
{
printf("----BBB\n");
return 0;
}
int funcb()
{
printf("BBB\n");
func();
return 0;
}
/* funcc.c */
#include <stdio.h>
int func()
{
printf("----CCC\n");
return 0;
}
int funcc()
{
printf("CCC\n");
func();
return 0;
}
/* funcd.c */
#include <stdio.h>
int func()
{
printf("DDD\n");
return 0;
}
int funcd()
{
printf("DDD\n");
func();
return 0;
}
ar rvu libfuncb.a funcb.c
gcc -shared -fPIC -o libfunca.so funca.c
gcc -shared -fPIC -o libfuncc.so funcc.c
gcc -shared -fPIC -o libfuncd.so funcd.c
(3)当链接的动态库A中未定义某函数接口,但编译该动态库A时链接的动态库B中有该接口定义,在编译该程序时无需链接动态库B依然不会报错
#include <stdio.h>
int funce()
{
printf("EEE\n");
return;
}