How To Write Shared Libraries(28)

2.2.4 Define Visibility for C++ Classes(2)

Because these problems are so hard to debug it is essential to get the compiler involved in making sure the user follows the necessary rules. The C++ type system is rich enough to help if the implementor puts some additional effort in it. The key is to mimic the actual symbol access as closely as possible with the class definition. For this reason the class definitions of the example above should actually look like this:
由于这个问题很难调试,所以编译器通过规则保证正确使用变得非常重要。c++类型系统有丰富的信息帮助开发者。关键是是最小化语法定义。因此,之前的定义修改如下:

class foo {
static int u __attribute__
((visibility ("hidden")));
  int a;
 public:
foo (int b = 1);
int val () const __attribute__
    ((visibility ("hidden")));
  void offset (int n);
};
class foo_ext : protected foo { public:
foo_ext (int b = 1) : foo (b) { } void offset (int n)
    { return foo::offset (n); }
};

The class foo is regarded as a private class, not to be used outside the DSO with the instantiation. The public interface would be the class foo ext. It provides access to the two public interfaces of the underlying class. As long as the users of the DSO containing the definitions respect the requirement that only foo ext can be used there is no way for the compiler not noticing accesses to foo::u and foo::val outside the DSO containing the definitions.
foo是私有类,不会导出DSO。开放的接口是ext。ext操作两个内部实现类。
只要包含定义的DSO的用户遵守只能使用foo ext的要求,编译器就不可能不注意在包含定义的DSO之外对foo::u和foo::val的访问。(有道翻译)

Template class and functions are not different. The syn- tax is the same. Non-inline function definitions get yet again less readable but that is something which can be mostly hidden with a few macros.
模版类和函数也一样。语法相同。
非内联函数定义的可读性仍然较差,但这可以用一些宏隐藏起来。(有道翻译)

template
class a {
T u; public:
a (T a = 0);
T r () const __attribute__
    ((visibility ("hidden")));
};
template a::a (T a)
{ u = a; }
template T
__attribute__ ((visibility ("hidden")))
 a::r () const { return u; }

For templatized classes the problems of making sure that if necessary only one definition is used is even harder to fix due to the various approaches to instantiation.
对于模板化的类,由于实例化的各种方法,在必要时确保只使用一个定义的问题更加难以解决。(有道翻译)

One sort of function which can safely be kept local and not exported are inline function, either defined in the class definition or separately. Each compilation unit must have its own set of all the used inline functions. And all the functions from all the DSOs and the executable better be the same and are therefore interchangeable.
一种可以安全地保持局部且不导出的函数是内联函数,它可以在类定义中定义,也可以单独定义。每个编译单元必须有自己的所有使用的内联函数集。来自所有DSOs和可执行文件的所有函数最好是相同的,因此是可互换的。(有道翻译)
It is possible to mark all inline functions explicitly as hidden but this is a lot of work.
Since version 4.0 gcc knows about the op- tion -fvisibility-inlines-hidden which does just what is wanted.
If this option is used a referenced in- line function is assumed to be hidden and an out-of-line copy of the function is marked with STV HIDDEN.
I.e., if the function is not inlined the separate function created is not exported.
This is a quite frequent situation at times since not all functions the programmer thinks should be inlined are eligible according to the compiler’s analysis.
This option is usable in almost all situations.
Only if the functions in the different DSOs can be different or if the code depends on exactly one copy of the function ever being used (e.g., if the function address is expected to be the same) should this option be avoided.
可以将所有内联函数显式地标记为隐藏,但这需要大量的工作。
因为4.0版本的gcc知道操作-fvisibility-inline -hidden,它只做我们想要的。
如果使用此选项,则假定引用的内联函数是隐藏的,并且该函数的一个行外副本被标记为STV hidden。
也就是说,如果函数没有内联,则单独创建的函数不会被导出。
这是一种非常常见的情况,因为根据编译器的分析,并非所有程序员认为应该内联的函数都符合条件。
这个选项几乎适用于所有情况。
只有当不同DSOs中的函数可能不同,或者代码依赖于曾经使用过的函数的一个副本时(例如,如果函数地址预期是相同的),才应该避免此选项。(有道翻译)

你可能感兴趣的:(How To Write Shared Libraries(28))