【问题标题】:Symbol Visibility in WindowsWindows 中的符号可见性
【发布时间】:2012-09-24 22:36:02
【问题描述】:

我在 linux 中进行了大量编程,我使用可见性属性来定义符号在共享对象中是可见还是隐藏。只是为了让事情更清楚:如果一个符号是可见的,它将可以从外部访问(与共享对象链接的人),如果它是隐藏的,它应该只在内部使用。

在 Windows 上,它似乎有点不同,它适用于导出(符号在此处在共享对象中定义,并且可以由与此链接的人访问)和导入(这里我与共享对象和符号在那里导出)符号。但是我找不到告诉编译器不要导出符号的方法,因为它只能在此处使用,即如果有人与它链接,则会出现链接器错误。

我的问题是我是否可以将符号定义为“隐藏”(如在 linux 的 gcc 中)以及如何定义。 此外,Windows 主题中的所有这些可见性对我来说有点模糊,我正在寻找一些进一步的阅读链接以更好地了解一切是如何工作的。

【问题讨论】:

  • 不是windows开发者,但是如果不导出(dllexport),是不是默认不可见
  • @DavidRodríguez-dribeas 我对 Visual Studio 的经验为零(现在开始制作与 msvc 兼容的代码),但在 mingw 上它似乎默认可见。
  • gcc.gnu.org/wiki/Visibility 双向显示。

标签: c++ windows visual-c++ mingw


【解决方案1】:

David Rodriguez 是正确的,在 MSVC 环境中,程序员通常通过特定于 MSVC 的 __declspec(dllexport) 修饰符显式导出函数/类符号。未显式导出的符号不应显示在已编译 DLL 的符号表中(您可以使用 dumpbin,Visual Studio 命令行实用程序之一,使用 /EXPORTS 选项进行验证)。导入该符号时使用 dllimport 是惯例,尽管我认为这是可选的。这通常是如何发挥作用的,定义 DLL 的公共接口的头文件将有一些宏默认扩展为 __declspec(dllimport),但在构建该库时设置为扩展为 __declspec(dllexport)。

请注意,GCC 和 MSVC 对待 dllexport 的方式可能不同;在隐藏未导出符号的意义上,也许 GCC 不“尊重” dllexport ?在尝试使用 GCC 之前,我会先尝试使用 MSVC 编译并使用 dumpbin 测试这些结果。如果您没有 Visual Studio,您仍然可以通过下载 VS Express 或(鲜为人知)通过下载命令行 MSVC 附带的某些 .NET 可再发行组件来获得 MSVC 编译器(这两个选项都是免费且合法的)。 VS Express 可能是更好的选择,因此您可以获取 dumpbin。

【讨论】:

  • 在 MSVC 下,您还可以通过模块定义文件 (.def) 导出,此时 declspecs() 可以完全扔到总线下(根据构建设置,有 是)。
  • @WhozCraig 之前没怎么用过 .def,但我相信你是对的。库作者在这两种方法之间做出选择,因此 .def 作为一个选项的存在希望不会阻止操作选择 dllexport 并使用它来半有效地限制 MSVC 下的可见性。
  • 完全。我过去发现,在 Windows 下的 DLL 中定义特定的公开条目so 比 Linux 干净得多,因为默认公开根本没有,但我花在一个比另一个上的时间更多,所以这无疑会影响我对此事的看法。
  • @WhozCraig 只需使用-fvisibility=hidden 作为 GCC 或 Clang 的命令行开关,您在 Linux/UNIX/MacOS X 上的行为完全相同:没有导出任何内容,除非您通过定义导出它代码中的不同可见性或将符号放入传递给编译器/链接器的符号文件中。
  • @Mecki 非常感谢。我真的需要花更多的时间在 gcc 的选项图表上。
猜你喜欢
  • 1970-01-01
  • 2011-06-27
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-10
  • 1970-01-01
  • 2017-02-20
相关资源
最近更新 更多