是否可以通过修改上面的编译命令来定制哪些函数是公开的?
No.编译选项
-fvisibility=[default|internal|hidden|protected]
(请注意
不
全部的
除了
通过反补贴被明确排除在外的
__attribute__((visibility(....)))
在源代码中
也不是。
将
您更改源代码以使
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;
}
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
另一方面,没有内联定义,因此编译器
发射全局符号和定义。
使
符合某种可见性类型,我们首先需要
它通过不内联定义来定义全局符号:
矩形.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()
矩形::面积
出现。
接下来,让我们创建一个共享库
librectangle.so
矩形.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()
下面是
矩形:*
动态
符号表:
$ 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
矩形:*
现在在全局符号表中的符号:
$ nm -C librectangle.so | grep 'Rectangle::'
0000000000000574 t Rectangle::set_values(int, int)
000000000000055a t Rectangle::area()
下面是
矩形:*
符号现在在
动态
$ nm -CD librectangle.so | grep 'Rectangle::'; echo Done
Done
没有人
,感谢
-可视性=隐藏
.
最后,让我们做一个
矩形::面积
动态可见,保持所有
再一次:
矩形.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++-o librectangle.so—共享矩形.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()
矩形::面积
现在是共享库为其公开的唯一符号
还有一件事:
是否可以将area()设置为public,并将\u值(int,int)设置为local,如第一个链接所示,而不更改代码?
为动态链接隐藏符号并不意味着
地方的
是的属性
全球的
地方的
符号不存在。唯一的办法
使符号成为本地的,否则将是全局的are:-
则符号不会出现在全局或动态符号表中。