__attribute__ ((visibility("default")))參考


原文:http://blog.csdn.net/starstarstone/article/details/7493144?utm_source=tuicool 
本文僅做備用,請參見原文。

gcc __attribute__關鍵字舉例之visibility

    visibility用於設置動態鏈接庫中函數的可見性,將變量或函數設置為hidden,則該符號僅在本so中可見,在其他庫中則不可見。

    g++在編譯時,可用參數-fvisibility指定所有符號的可見性(不加此參數時默認外部可見,參考man g++中-fvisibility部分);若需要對特定函數的可見性進行設置,需在代碼中使用__attribute__設置visibility屬性。

    編寫大型程序時,可用-fvisibility=hidden設置符號默認隱藏,針對特定變量和函數,在代碼中使用__attribute__ ((visibility("default")))另該符號外部可見,這種方法可用有效避免so之間的符號沖突。

    下面是visibility的實例,這里extern “C”可以省略(另外兩篇文章gcc __attribute__關鍵字舉例之alias C++覆蓋系統函數的方法 中extern "C"不可用省略)。

    值得注意的是,visibility2.cc中可以調用fun1,原因是visibility1.o和visibility2.o同屬於一個so文件。 

  visibility1.cc:

#include <stdio.h>  
extern "C" void fun1()  
{  
  printf("in %s\n",__FUNCTION__);  
}  
__attribute__ ((visibility("hidden"))) void fun1();//若編譯此文件時使用了參數-fvisibility=hidden,則此行可以省略  

 visibility2.cc:

#include <stdio.h>  
extern "C" void fun1();  
extern "C" void fun2()  
{  
  fun1();  
  printf("in %s\n",__FUNCTION__);  
}  
__attribute__ ((visibility("default"))) void fun2();//若編譯此文件時沒有使用參數-fvisibility或設置參數-fvisibility=default,則此行可以省略 

main.cc:

extern "C" void fun1();  
extern "C" void fun2();  
int main()  
{  
  fun1();  
  fun2();  
  return 0;  
} 

Makefile:

all:test  
test:main.o libvisibility.so  
        g++ -o test main.o -lvisibility -L .  
main.o::main.cc  
        g++ -c main.cc  
libvisibility.so:visibility1.o visibility2.o  
        g++ -shared -o libvisibility.so visibility1.o visibility2.o  
visibility1.o:visibility1.cc  
        g++ -fvisibility=hidden -fPIC -c visibility1.cc  
visibility2.o:visibility2.cc  
        g++ -fvisibility=hidden -fPIC -c visibility2.cc  
clean:  
        rm -f *.o *.so test  
編譯和輸出:
$ make  
g++ -c main.cc  
g++ -fvisibility=hidden -fPIC -c visibility1.cc  
g++ -fvisibility=hidden -fPIC -c visibility2.cc  
g++ -shared -o libvisibility.so visibility1.o visibility2.o  
g++ -o test main.o -lvisibility -L .  
main.o: In function `main':  
main.cc:(.text+0x5): undefined reference to `fun1'  
collect2: ld returned 1 exit status  
make: *** [test] Error 1   
可以看到,main()中可以不可用調用fun1,可以調用fun2,因為fun1已經設置為外部不可見,fun2設置為外部可見。

使用readelf對各個.o文件分析可以看到,fun1的Vis屬性為HIDDEN,fun2的Vis屬性為DEFAULT:

$ readelf -s visibility1.o|grep fun  
     6: 0000000000000007     5 OBJECT  LOCAL  DEFAULT    6 _ZZ4fun1E12__FUNCTION__  
    12: 0000000000000000    30 FUNC    GLOBAL HIDDEN    2 fun1  
  
$ readelf -s visibility2.o|grep fun  
     6: 0000000000000007     5 OBJECT  LOCAL  DEFAULT    6 _ZZ4fun2E12__FUNCTION__  
    12: 0000000000000000    35 FUNC    GLOBAL DEFAULT    2 fun2  
    15: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND fun1  
  
$ readelf -s libvisibility.so|grep fun  
     9: 00000000000006ac    35 FUNC    GLOBAL DEFAULT   12 fun2  
    41: 000000000000071d     5 OBJECT  LOCAL  DEFAULT   14 _ZZ4fun1E12__FUNCTION__  
    43: 0000000000000729     5 OBJECT  LOCAL  DEFAULT   14 _ZZ4fun2E12__FUNCTION__  
    48: 000000000000068c    30 FUNC    LOCAL  HIDDEN   12 fun1  
    54: 00000000000006ac    35 FUNC    GLOBAL DEFAULT   12 fun2  

參考:

Function Attributes

Visibility Pragmas

GCC擴展 __attribute__ ((visibility("hidden")))


免責聲明!

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



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