__attribute__((visibility("default"))) [轉]


-fvisibility=default|internal|hidden|protected

gcc的visibility是說,如果編譯的時候用了這個屬性,那么動態庫的符號都是hidden的,除非強制聲明。

1.創建一個c源文件,內容簡單
#include<stdio.h>
#include<stdlib.h>


__attribute ((visibility("default"))) void not_hidden ()
{
printf("exported symbol/n");
}

void is_hidden ()
{
printf("hidden one/n");
}

想要做的是,第一個函數符號可以被導出,第二個被隱藏。
先編譯成一個動態庫,使用到屬性-fvisibility
gcc -shared -o libvis.so -fvisibility=hidden vis.c

現在查看
# readelf -s libvis.so |grep hidden
7: 0000040c 20 FUNC GLOBALDEFAULT11 not_hidden
48: 00000420 20 FUNC LOCALHIDDEN 11 is_hidden
51: 0000040c 20 FUNC GLOBAL DEFAULT 11 not_hidden
可以看到,屬性確實有作用了。

現在試圖link
vi main.c
int main()
{
not_hidden();
is_hidden();
return 0;
}

試圖編譯成一個可執行文件,鏈接到剛才生成的動態庫,
gcc -o exe main.c -L ./ -lvis
結果提示:

/tmp/cckYTHcl.o: In function `main':
main.c:(.text+0x17): undefined reference to `is_hidden'

說明了hidden確實起到作用了。

__attribute__((visibility("default")))

 試想這樣的情景,程序調用某函數A,A函數存在於兩個動態鏈接庫liba.so,libb.so中,並且程序執行需要鏈接這兩個庫,此時程序調用的A函數到底是來自於a還是b呢?
 這取決於鏈接時的順序,比如先鏈接liba.so,這時候通過liba.so的導出符號表就可以找到函數A的定義,並加入到符號表中,鏈接libb.so的時候,符號表中已經存在函數A,就不會再更新符號表,所以調用的始終是liba.so中的A函數。
 為了避免這種混亂,所以使用__attribute__((visibility("default")))__attribute__((visibility("hideen"))) 設置這個屬性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM