__attribute__((weak))

情况是这样的,碰到一个棘手的问题:我们不确定外部模块是否提供一个函数func,但是我们不得不用这个函数,即自己模块的代码必须用到func函数:

extern int func(void);

...................

int a = func();

if( a > .....)

{

..........

}

............

我们不知道func函数是否被定义了

这会导致2个结果:

1:外部存在这个函数func,并且EXPORT_SYMBOL(func),那么在我自己的模块使用这个函数func,正确。

2:外部其实不存在这个函数,那么我们使用func,程序直接崩溃。

 

所以这个时候,__attribute__((weak)) 派上了用场。

在自己的模块中定义:

int  __attribute__((weak))  func(......)

{

return 0;

}

 

将本模块的func转成弱符号类型,如果遇到强符号类型(即外部模块定义了func),那么我们在本模块执行的func将会是外部模块定义的func。

如果外部模块没有定义,那么,将会调用这个弱符号,也就是在本地定义的func,直接返回了一个1(返回值视具体情况而定)

相当于增加了一个默认函数。

原理:连接器发现同时存在弱符号和强符号,有限选择强符号,如果发现不存在强符号,只存在弱符号,则选择弱符号。如果都不存在:静态链接,恭喜,编译时报错,动态链接:对不起,系统无法启动。 

 

TIPS

weak属性只会在静态库(.o .a )中生效,动态库(.so .ko(内核模块))中不会生效。

 

举个例子:

strong.c  //生成libstrong.so

 

#include <stdio.h>

void real_func()
{
	printf("int real func\n");
}


weak.c //生成libweak.so

 

 

#include <stdio.h>
void real_func() __attribute__((weak));


void real_func()
{
	printf("fake func\n");
}


main.c //

 

 

#include <stdio.h>
extern void real_func();

void main()
{
        real_func();
}

 

 

 

 

 

如果 

gcc main.c -lstrong -lweak

那么输出结果"real func"。

 

如果 

gcc main.c -lweak -lstrong

那么输出结果为"fake func"。

 

可见,对于动态库,weak属性毫无作用,且main中调用哪个real_func(),取决于链接的顺序。

 

如果将strong.c 和 weak.c编译成.a或者.o

gcc main.c strong.o weak.o

或者

gcc main.c strong.o weak.o

那么输出结果都是"real func"。

所以,如果在so中使用weak属性,那么任何不符合预期的情况,都是可能出现的。

官方解释:

https://sourceware.org/bugzilla/show_bug.cgi?id=3946

如果你觉得有用,请打赏http://39.98.242.44/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值