C语言之__attribute__((visibility(“default“)))等gcc flag讲解(六十二)
创始人
2024-03-15 20:24:05
0

目录

1.概述

2.程序说明

<1>.test.h

<2>.test.c

<3>.main.c

3.编译实验

<1>.gcc显示声明:-fvisibility=default

<2>.gcc显示声明:-fvisibility=hidden

<3>.gcc显示声明:-fvisibility=internal

<4>.gcc显示声明:-fvisibility=protected


1.概述

-fvisibility=default / internal / hidden / protected

上述表示:

 <1>.gcc在编译动态库的时候visibility有四个选项,只有使用default和protected选项编译时,编译出来的动态库的符号是可以被外界调用的;

 <2>.而编译时使用internal和hidden选项时,如果函数内没有:__attribute ((visibility("default")))声明,动态库使隐藏的不可被外界调用。

2.程序说明

<1>.test.h

#include__attribute ((visibility("default"))) void test_01();
void test_02();

<2>.test.c

#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__);
}

<3>.main.c

#include "test.h"
int main(){test_01();test_02();return 0;
}

3.编译实验

<1>.gcc显示声明:-fvisibility=default

编译动态库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_027: 0000000000001119    41 FUNC    GLOBAL DEFAULT   14 test_0122: 0000000000001119    41 FUNC    GLOBAL DEFAULT   14 test_0126: 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()

<2>.gcc显示声明:-fvisibility=hidden

编译动态库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_0117: 0000000000001142    41 FUNC    LOCAL  DEFAULT   14 test_0223: 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()函数不可以被导出和调用。

<3>.gcc显示声明:-fvisibility=internal

编译动态库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_0117: 0000000000001142    41 FUNC    LOCAL  DEFAULT   14 test_0223: 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()函数不可以被导出和调用。

<4>.gcc显示声明:-fvisibility=protected

 编译动态库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_027: 0000000000001119    41 FUNC    GLOBAL DEFAULT   14 test_0122: 0000000000001119    41 FUNC    GLOBAL DEFAULT   14 test_0126: 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()

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...