【发布时间】:2014-12-05 17:09:00
【问题描述】:
在his paper about shared libraries 中,Ulrich Drepper 建议在构建库时将符号可见性全局设置为 hidden,然后在源代码中设置为 default每个符号都是公开的以导出它。但是,在搜索之后,我仍然不明白应该在哪里指定 visibility 属性:在 declarations 中,还是在 definitions 中?由于任何不属于接口的符号都不会在公共标头中声明,我认为后一个选项更好,但this page from Microsoft 让我怀疑:那里,似乎在标头中设置了相应的属性.
例如,在 libwayland(Wayland 协议的开源实现)中,它是这样完成的:
void wl_event_queue_destroy(struct wl_event_queue *);
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