【问题标题】:Should the visibility attribute be specified in declarations or in definitions?是否应该在声明或定义中指定可见性属性?
【发布时间】:2014-12-05 17:09:00
【问题描述】:

his paper about shared libraries 中,Ulrich Drepper 建议在构建库时将符号可见性全局设置为 hidden,然后在源代码中设置为 default每个符号都是公开的以导出它。但是,在搜索之后,我仍然不明白应该在哪里指定 visibility 属性:在 declarations 中,还是在 definitions 中?由于任何不属于接口的符号都不会在公共标头中声明,我认为后一个选项更好,但this page from Microsoft 让我怀疑:那里,似乎在标头中设置了相应的属性.

例如,在 libwayland(Wayland 协议的开源实现)中,它是这样完成的:

wayland-client.h:

void wl_event_queue_destroy(struct wl_event_queue *);

wayland-client.c:

WL_EXPORT void
wl_event_queue_destroy(struct wl_event_queue *)
{
    /* ... */
}

我担心与其他编译器和平台的兼容性:GCC、Clang、MSVC、... 另请注意,这个问题也适用于 C++。

【问题讨论】:

  • 公共标头绝对可以包含不可见导出的代码,例如结构定义、常量、内联函数等。虽然这可能是不好的做法,但它也可以声明只能在 dll 内部使用的函数。在标头中包含符号可以允许在导入文件时使用花哨的技巧(例如 MSVC 中的隐式链接)。当然,这完全取决于平台,因为在 ELF 和 DLL 中公开公共符号的方式不同。所以呃...你的问题是什么?
  • @MadScienceDreams 我的问题是:应该在哪里指定 visibility (GCC) 属性:在声明(标题)或定义(源文件)中?我还担心这在“符号可见性”概念的所有实现中是否相同,即答案是否适用于 Microsoft 的 dllexport
  • 快速回答是它不适用于微软dllexport/dllimport。所有声明必须有其中之一,所有定义必须有dllexport。见msdn.microsoft.com/en-us/library/y4h7bcy6.aspx。对于可交叉编译的代码,我会将ifdef 宏放在标头中以指定编译器,将宏定义为正确的值,然后将其放入两者中

标签: c++ c visual-c++ gcc clang


【解决方案1】:

这对 GNU 来说并不重要,但在 Windows 标头声明中无论如何都需要使用 dllimports 进行注释,因此习惯上也将可见性注释放在那里。

请注意,仅在编译库本身时才需要启用可见性注释,而不是在编译仅调用库函数的代码时,因此大多数项目都会执行类似的操作

#ifndef WL_EXPORT
# define WL_EXPORT
#endif

在标题中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2014-04-25
    • 2021-12-19
    相关资源
    最近更新 更多