情況是這樣的,碰到一個棘手的問題:我們不确定外部子產品是否提供一個函數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/