出口制造商,符号可见性,...?

Posted

技术标签:

【中文标题】出口制造商,符号可见性,...?【英文标题】:Export Makers, Symbol Visibility, ...? 【发布时间】:2016-02-26 22:18:50 【问题描述】:

我正在尝试开发一个必须独立于平台的库。在编写库 API 时,使用一些预处理器定义为函数添加一些前缀是一种很好的做法。

例如,Windows API 有 WINAPI,OpenMPI 有 OMPI_DECLSPEC 等等……

OpenMPI:

OMPI_DECLSPEC  int MPI_Init(int *argc, char ***argv);

OpenGL:

GLAPI void GLAPIENTRY glBegin( GLenum mode );

通过这个预处理器定义,程序员可以为库中的函数设置导出选项、可见性和调用约定。如您所见,在 OpenGL 函数声明中,有两种不同的预处理器定义。

这个前缀在文献中叫什么名字?

编辑: https://gcc.gnu.org/wiki/Visibility 在此页面中,讨论了该主题。我认为,这种宏应该有一个特殊的名称。我们可以将其命名为“可见性宏”之类的,但是这个宏可以根据编译器、操作系统等设置其他类型的东西……

【问题讨论】:

你几个小时前已经发布了同样的问题!不!如果问题已关闭,请编辑以符合站点规则并要求重新打开。此外,它在很大程度上取决于您使用的语言。 C 和 C++ 是不同的语言。不要要求两种语言的解决方案,而只要求您打算使用的一种。 不,他们不能。您只需使用非常小的通用子集或使用 C++ 编译器编译 C 语法,忽略不同的语义并希望获得最好的结果。无论如何,你错过了真正的重点。 【参考方案1】:

这个前缀在文献中叫什么名字?

他们被称为macros。它们有助于 C 和 C++ 语言中的条件编译。在过去,它们也被用作typedefs 的替代品。以GLAPIENTRY 为例,它是这样定义的:

#define GLAPIENTRY __stdcall

如果作者必须将调用约定更改为__cdecl,如果__stdcall 直接放在函数声明中,那么对于每个函数都必须更改此值。但是,使用宏,只需重新定义即可:

#define GLAPIENTRY __cdecl

【讨论】:

感谢您的回答,我认为这种宏应该有一个特殊的名称。 当然,他们可能应该得到一个特殊的名字,但我认为他们还没有一个。【参考方案2】:

据我所知,这些类型的宏没有特定的名称,但如果我必须给它们起一个名字,我必须将它们标记为“上下文宏”或(更具体到函数)“函数属性可移植性上下文宏”,因为它们通常是根据编译单元的上下文定义的。

这可以进一步分为其他类别:

可移植性宏 例如: __attribute__()__declspec() __attribute__((always_inline))__forceinline 或将不受支持的属性定义为空 编译上下文staticextern 可见性上下文宏(隐藏、默认、受保护、内部/符号...)

可移植性上下文宏用于克服编译器和/或主机/目标架构与操作系统之间的差异。这些不仅涵盖可见性之间的差异(包括任何特殊功能属性)

编译上下文宏可以允许使用相同的源代码高效地编译不同类型的编译,例如静态与 PIC 以及库与二进制。这些可能包括各种内联或可见性指令,具体取决于编译上下文。

在给出的例子中

GLAPI void GLAPIENTRY glBegin( GLenum mode );

GLAPI 表示编译上下文(可能还带有相关的可移植宏),GLAPIENTRY 只是一组特定的可移植宏包装器函数属性(它是一个“跨平台”API)。

【讨论】:

以上是关于出口制造商,符号可见性,...?的主要内容,如果未能解决你的问题,请参考以下文章

链接共享库时限制符号的可见性

符号可见性和 gcc 警告

使用 g++ 的符号可见性

如果类没有默认可见性,如何使静态断言失败

GCC:内部可见性“在现实世界的使用中毫无用处”?

可见性原子性有序性