【问题标题】:C++ [[gnu::visibility("default")]] vs __declspec(dllexport) on Windows and LinuxWindows 和 Linux 上的 C++ [[gnu::visibility("default")]] vs __declspec(dllexport)
【发布时间】:2014-02-15 15:10:18
【问题描述】:

我需要用 C++ 制作一些共享库,并且我使用 linux 作为我的开发人员操作系统。我知道如果我想通过dlsym/LoadLibrary 加载符号,我需要使它们可见。所以在linux中我所有的符号都遵循这个模式:

extern "C" [[gnu::visibility("default")]] void f();

我在启用 C++11 的情况下使用了 clang,并且能够在我的主机程序中加载 f。当我迁移到 Windows 时,我使用了启用 C++11 的 GCC 4.8.2,并且该模式在 Windows 机器上也可以使用LoadLibrary。 (我需要将 C++11 用于新的属性语法)。我知道在 Windows 上我需要使用 __declspec(dllexport) 从共享库中导出符号。所以现在怎么办? __declspec(dllexport) 不再需要了吗?

编辑:

我发现here 是同义词(我认为)所以问题是__declspec(dllimport) 是否有[[gnu::attribute]] 以避免使用宏和ifdefs 用于特定目标?

【问题讨论】:

    标签: c++ attributes visibility declspec


    【解决方案1】:

    符号可见性与dllexport略有不同——主要原因是当你在Windows下mingw/cygwin下编译.dll时,默认behaviour of the linker是选项-export-all-symbols——即默认情况下,它会自动从您的.dll 导出所有内容

    您可以通过使用.def 文件或将__declspec((dllexport))__attribute((dllexport)) 放在any 例程上来更改此行为(即,如果您指定要导出单个符号,则仅导出声明为导出的符号)。如果您的库中有很多符号,这可以在 dll 加载时显着提高性能。

    如果要使用等效的C++ 属性,则使用[[gnu::dllexport]]

    所以,是的,使用dllexport 来阻止您的.dll 输出世界。

    以类似的方式,您可以使用[[gnu:dllimport]] 导入外部例程。

    阅读文档时要小心;它实际上说的是,当您使用 dllexport 属性时,它还会触发 visibility:default 行为,除非它被覆盖。

    【讨论】:

    • 据我了解,[[gnu::dllexport]] 仅适用于 GCC,不是吗?有没有这样的东西,也可以在 Clang 和 MSVC 下工作?
    • 它也适用于 clang。 MSVC 没有同等功能,因此如果您想要全面兼容的代码,您可能不得不求助于宏。所有三个编译器都支持使用__declspec((dllexport|dllimport)),所以你可以使用它,但它不是“干净的”C++。如果要保证平台兼容代码,则只能依赖标准指定的[[ ]] 属性。
    猜你喜欢
    • 1970-01-01
    • 2018-08-05
    • 2023-01-26
    • 2015-02-24
    • 2016-03-25
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    相关资源
    最近更新 更多