赞
踩
main(主程序) --> calltest()函数 (libcalltest.so) --> funtest()函数
funtest()函数有两个地方实现,动态库是weak类型的实现,静态库是默认类型。期望是可以屏蔽掉动态库里的实现,调用到静态库中,但实际调用和链接顺序有关。
[func]$ nm -D libfuntest.so
0000000000000685 W funtest
[func]$ nm -A libstfunctest.a
libstfunctest.a:stfunctest.o:0000000000000000 T funtest
#include <stdio.h>
#include <stdlib.h>
extern void calltest();
int main(void)
{
calltest();
return 0;
}
#include <stdlib.h>
#include <stdio.h>
extern void funtest();
void calltest (void)
{
printf("This is calltest, call funtest\n");
funtest();
}
编译libcalltest.so
gcc -fPIC -c calltest.c -o libcalltest.o
gcc -shared -o libcalltest.so libcalltest.o
或
gcc -fPIC -shared calltest.c -o libcalltest.so
#include <stdlib.h>
#include <stdio.h>
void funtest (void)
{
printf("This is a funtest\n");
}
编译libstfunctest.a
gcc -c stfunctest.c -o stfunctest.o
ar rc libstfunctest.a stfunctest.o
#include <stdlib.h>
#include <stdio.h>
#define weak_alias(name, aliasname) _weak_alias (name, aliasname)
#define _weak_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
void __funtest (void)
{
printf("This is so funtest\n");
}
weak_alias (__funtest, funtest)
编译libcalltest.so
gcc -fPIC -c funtest.c -o libfuntest.o
gcc -shared -o libfuntest.so libfuntest.o
动态库路径:
export LD_LIBRARY_PATH=/home/test/func:$LD_LIBRARY_PATH
[func]$ gcc main.c -L. -lcalltest -lstfunctest -lfuntest
[func]$ ./a.out
This is calltest, call funtest
This is a funtest
[func]$ gcc main.c -L. -lfuntest -lstfunctest -lcalltest
[func]$ ./a.out
This is calltest, call funtest
This is so funtest
[func]$ gcc main.c -L. -lstfunctest -lfuntest -lcalltest
[func]$ ./a.out
This is calltest, call funtest
This is so funtest
[func]$ gcc main.c -L. -lstfunctest -lcalltest -lfuntest
[func]$ ./a.out
This is calltest, call funtest
This is so funtest
[func]$ gcc main.c -L. -lcalltest -lfuntest -lstfunctest
[func]$ ./a.out
This is calltest, call funtest
This is so funtest
[func]$ gcc main.c -L. -lfuntest -lcalltest -lstfunctest
[func]$ ./a.out
This is calltest, call funtest
This is so funtest
默认情况下,对于未使用到的符号,链接器不会将它们链接进共享库和可执行程序,也就是默认参数为-Wl,-no-whole-archive
综上,想要静态库-lstfunctest被链接进去,第一个链接的库必须是调用库-lcalltest,链接器才知道有对应的符号需要被链接。其次静态库-lstfunctest必须在动态库-lfuntest之前;否则先链接的动态库中符号,之后因为已链接符号则不会再把静态库链接进来。
也可以改成将静态库符号全部链进来:
gcc main.c -L. -Wl,--whole-archive -lstfunctest -Wl,--no-whole-archive -lcalltest -lfuntest
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。