gpt4 book ai didi

c++ - 如何使用 __attribute__((visibility ("default")))?

转载 作者:IT王子 更新时间:2023-10-29 00:26:03 28 4
gpt4 key购买 nike

阅读 Visibility在 GNU wiki 中,很清楚。

服用 this来自 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

最佳答案

Is it possible to customize which functions are exposed by modifying the compilation command above?

没有。编译选项 -fvisibility=[default|internal|hidden|protected](注意它不是链接选项)使编译器将指定的动态可见性类型归于所有全局符号在编译单元中生成 except 那些通过反补贴 __attribute__((visibility(....))) 特别排除的那些在源代码中应用。这就是您其他问题的答案:

Is it possible to make area() public and set_values(int,int) local as shown in the first link without altering the code?

也没有。

如何更改源代码以动态生成 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 的全局定义。

接下来让我们从 rectangle.o 创建一个共享库 librectangle.so:

$ 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 现在是共享库公开的唯一符号动态联动。

在你走之前......

还有一点:

Is it possible to make area() public and set_values(int,int) local as shown in the first link without altering the code?

为动态链接隐藏符号并不会使其成为本地。动态可见性(默认|内部|隐藏|保护)仅是全局 符号的属性。出于链接目的,本地 符号不存在。唯一的方法制作一个局部的符号,否则它是全局的:-

然后该符号不会出现在全局或动态符号表中。

关于c++ - 如何使用 __attribute__((visibility ("default")))?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52719364/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com