目录
<1>.gcc显示声明:-fvisibility=default
<2>.gcc显示声明:-fvisibility=hidden
<3>.gcc显示声明:-fvisibility=internal
<4>.gcc显示声明:-fvisibility=protected
-fvisibility=default / internal / hidden / protected
上述表示:
<1>.gcc在编译动态库的时候visibility有四个选项,只有使用default和protected选项编译时,编译出来的动态库的符号是可以被外界调用的;
<2>.而编译时使用internal和hidden选项时,如果函数内没有:__attribute ((visibility("default")))声明,动态库使隐藏的不可被外界调用。
- #include
-
- __attribute ((visibility("default"))) void test_01();
- void test_02();
- #include "test.h"
-
- //test_01表示是"default"显示定义,说明可以被外界函数调用和导出。
- __attribute ((visibility("default"))) void test_01 (){
- printf("xxx------->%s()\n",__FUNCTION__);
- }
-
- //test_01表示隐士定义,如果gcc编译时,参数为-fvisibility=hidden,则不能被导出和外界调用。
- void test_02(){
- printf("xxx------->%s()\n",__FUNCTION__);
- }
- #include "test.h"
- int main(){
- test_01();
- test_02();
- return 0;
- }
编译动态库libtest.so:
# gcc -fPIC -shared -o libtest.so -fvisibility=default test.c
查看动态库符号表状态:
- # readelf -s libtest.so |grep test_
- 6: 0000000000001142 41 FUNC GLOBAL DEFAULT 14 test_02
- 7: 0000000000001119 41 FUNC GLOBAL DEFAULT 14 test_01
- 22: 0000000000001119 41 FUNC GLOBAL DEFAULT 14 test_01
- 26: 0000000000001142 41 FUNC GLOBAL DEFAULT 14 test_02
- 注意:
- 可以看到test_01()和test_02()函数都是GLOBAL DEFAULT状态,说明此libtest.so可以被外界导出和调用的。
-
编译main.c,并链接到libtest.so:
# gcc main.c -L ./ -ltest -o main
编译无报错,说明libtest.so里的两个函数都可以被导出和调用。
运行
- # export LD_LIBRARY_PATH=.
- # ./main
- xxx------->test_01()
- xxx------->test_02()
编译动态库libtest.so:
# gcc -fPIC -shared -o libtest.so -fvisibility=hidden test.c
查看动态库符号表状态:
- # readelf -s libtest.so |grep test_
- 6: 0000000000001119 41 FUNC GLOBAL DEFAULT 14 test_01
- 17: 0000000000001142 41 FUNC LOCAL DEFAULT 14 test_02
- 23: 0000000000001119 41 FUNC GLOBAL DEFAULT 14 test_01
-
- 注意:
- test_02()函数为LOCAL DEFAULT局部函数,说明不能被外界导出和调用。因为在test_02()函数没有
- 声明__attribute ((visibility("default"))),所以为局部隐藏,不能被外界调用。
编译main.c,并链接到libtest.so:
- # gcc main.c -L ./ -ltest -o main
- /usr/bin/ld: /tmp/ccD5TD6O.o: in function `main':
- main.c:(.text+0x18): undefined reference to `test_02'
- collect2: error: ld returned 1 exit status
编译报错,说明libtest.so里的test_02()函数不可以被导出和调用。
编译动态库libtest.so:
# gcc -fPIC -shared -o libtest.so -fvisibility=internal test.c
查看动态库符号表状态:
- # readelf -s libtest.so |grep test_
- 6: 0000000000001119 41 FUNC GLOBAL DEFAULT 14 test_01
- 17: 0000000000001142 41 FUNC LOCAL DEFAULT 14 test_02
- 23: 0000000000001119 41 FUNC GLOBAL DEFAULT 14 test_01
-
- 注意:
- test_02()函数为LOCAL DEFAULT局部函数,说明不能被外界导出和调用。因为在test_02()函数没有
- 声明__attribute ((visibility("default"))),所以为局部隐藏,不能被外界调用。
编译main.c,并链接到libtest.so:
- # gcc main.c -L ./ -ltest -o main
- /usr/bin/ld: /tmp/ccD5TD6O.o: in function `main':
- main.c:(.text+0x18): undefined reference to `test_02'
- collect2: error: ld returned 1 exit status
编译报错,说明libtest.so里的test_02()函数不可以被导出和调用。
编译动态库libtest.so:
# gcc -fPIC -shared -o libtest.so -fvisibility=protected test.c
查看动态库符号表状态:
- # readelf -s libtest.so |grep test_
- 6: 0000000000001142 41 FUNC GLOBAL DEFAULT 14 test_02
- 7: 0000000000001119 41 FUNC GLOBAL DEFAULT 14 test_01
- 22: 0000000000001119 41 FUNC GLOBAL DEFAULT 14 test_01
- 26: 0000000000001142 41 FUNC GLOBAL DEFAULT 14 test_02
- 注意:
- 可以看到test_01()和test_02()函数都是GLOBAL DEFAULT状态,说明此libtest.so可以被外界导出和调用的。
-
编译main.c,并链接到libtest.so:
# gcc main.c -L ./ -ltest -o main
编译无报错,说明libtest.so里的两个函数都可以被导出和调用。
运行
- # export LD_LIBRARY_PATH=.
- # ./main
- xxx------->test_01()
- xxx------->test_02()