如何使用__attribute__((visibility("default")))?
- 2024-11-07 08:55:00
- admin 原创
- 32
问题描述:
阅读GNU wiki 中的Visibility,就很清楚了。
以C++ 教程中的示例为例
// classes example
#include <iostream>
using namespace std;
class Rectangle {
int width, height;
public:
void set_values (int,int);
int area() {return width*height;}
};
void Rectangle::set_values (int x, int y) {
width = x;
height = y;
}
是否可以在不改变代码的情况下,像第一个链接中显示的那样将其设为area()
公开和本地?set_values(int,int)
我编写了 makefile 来获取.so
someproj.so : someproj.cpp
g++ --std=c++11 -O3 -fPIC -shared someproj.cpp -o someproj.so
修改为通过添加隐藏所有符号-fvisibility=hidden
someproj.so : someproj.cpp
g++ --std=c++11 -O3 -fvisibility=hidden -fPIC -shared someproj.cpp -o someproj.so
是否可以通过修改上面的编译命令来定制公开哪些函数?
目前使用 4.7.2 版本的 gcc
解决方案 1:
是否可以通过修改上面的编译命令来定制公开哪些函数?
否。编译选项-fvisibility=[default|internal|hidden|protected]
(请注意,它不是链接选项)使编译器将指定的动态可见性类型归因于编译单元中生成的所有全局符号,但通过在源代码中
应用抵消而明确排除的符号除外。这回答了你的另一个问题:__attribute__((visibility(....)))
是否可以使 area() 成为公共的,并将 set_values(int,int) 设为本地的,如第一个链接所示,而无需改变代码?
也沒有
如何更改源代码以使动态可见,Rectangle::area()
同时隐藏所有其他全局符号以进行动态链接-fvisibility=hidden
? 以下是一个演练:
让我们从以下开始:
矩形.cpp (1)
class Rectangle {
int width, height;
public:
void set_values (int,int);
int area() {return width*height;}
};
void Rectangle::set_values (int x, int y) {
width = x;
height = y;
}
然后简单地将其编译为 PIC,rectangle.o
如下所示:
$ g++ -Wall -c -fPIC rectangle.cpp
然后检查全局符号表:
$ nm -C rectangle.o
0000000000000000 T Rectangle::set_values(int, int)
注意Rectangle::area
不存在。它根本无法进行链接,因此其动态可见性的问题根本不存在。
这是因为它在类定义中以内联方式定义,并且从未在编译单元中调用,因此 gcc 甚至不需要编译其定义。它会从目标文件中消失。
Rectangle::set_values
另一方面,没有内联定义,因此编译器发出一个全局符号和定义。
为了使其Rectangle::area
符合某些可见性类型,我们首先需要通过不将其定义在内联来使其成为全局符号:
矩形.cpp (2)
class Rectangle {
int width, height;
public:
void set_values (int,int);
int area();
};
int Rectangle::area() {return width*height;}
void Rectangle::set_values (int x, int y) {
width = x;
height = y;
}
重新编译并再次检查全局符号表:
$ g++ -Wall -c -fPIC rectangle.cpp
$ nm -C rectangle.o
000000000000001a T Rectangle::set_values(int, int)
0000000000000000 T Rectangle::area()
很好。现在出现了的全局定义Rectangle::area
。
接下来让我们创建一个共享librectangle.so
库rectangle.o
:
$ g++ -o librectangle.so --shared rectangle.o
以下是Rectangle::*
其全局符号表中的符号:
$ nm -C librectangle.so | grep 'Rectangle::'
00000000000005d4 T Rectangle::set_values(int, int)
00000000000005ba T Rectangle::area()
以下是Rectangle::*
其动态符号表中的符号:
$ nm -CD librectangle.so | grep 'Rectangle::'
00000000000005d4 T Rectangle::set_values(int, int)
00000000000005ba T Rectangle::area()
它们是一样的。
现在让我们隐藏这些符号以进行动态链接。我们需要重新编译 rectangle.cpp
然后重新链接共享库:
$ g++ -Wall -c -fPIC -fvisibility=hidden rectangle.cpp
$ g++ -o librectangle.so --shared rectangle.o
Rectangle::*
现在全局符号表中的符号如下:
$ nm -C librectangle.so | grep 'Rectangle::'
0000000000000574 t Rectangle::set_values(int, int)
000000000000055a t Rectangle::area()
它们和以前一样。
Rectangle::*
现在动态符号表中的符号如下:
$ nm -CD librectangle.so | grep 'Rectangle::'; echo Done
Done
现在没有了,感谢-fvisibility=hidden
。
最后,让我们只让Rectangle::area
动态可见,而让所有其他全局符号保持动态隐藏。我们需要再次更改源代码:
矩形.cpp (3)
class Rectangle {
int width, height;
public:
void set_values (int,int);
__attribute__((visibility("default"))) int area();
};
int Rectangle::area() {return width*height;}
void Rectangle::set_values (int x, int y) {
width = x;
height = y;
}
然后重新编译并重新链接:
$ g++ -Wall -c -fPIC -fvisibility=hidden rectangle.cpp
$ g++ -o librectangle.so --shared rectangle.o
全局符号表仍然显示:
$ nm -C librectangle.so | grep 'Rectangle::'
00000000000005a4 t Rectangle::set_values(int, int)
000000000000058a T Rectangle::area()
而动态符号表只显示:
$ nm -CD librectangle.so | grep 'Rectangle::'
000000000000058a T Rectangle::area()
Rectangle::area
现在是共享库为动态链接公开的唯一符号。
在您离开之前...
还有一件事:
是否可以使 area() 成为公共的,并将 set_values(int,int) 设为本地的,如第一个链接所示,而无需改变代码?
为动态链接隐藏符号并不会使其成为本地符号。动态可见性(默认|内部|隐藏|受保护)只是全局符号的属性。对于链接目的,不存在本地符号。将原本是全局符号的符号变为本地符号的唯一方法是:-
在 C 或 C++ 源代码中,使用
static
关键字限定其定义在 C++ 源代码中,将其定义放在匿名命名空间中
那么该符号就不会出现在全局或动态符号表中。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件