Windows [和Linux]上的C [[gnu :: visibility(“default”)]] vs __declspec(dllexport)

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

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

我使用C11启用了clang,我能够在我的宿主程序中加载f.当我移动到Windows时,我使用GCC 4.8.2启用了C 11,并且该模式也在Windows机器上使用LoadLibrary. (我需要使用C 11作为新的属性语法).我知道在Windows上我需要使用__declspec(dllexport)从共享库中导出符号.所以现在怎么办?是不是还需要__declspec(dllexport)?

编辑:

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

解决方法:

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

您可以通过使用.def文件或在任何例程上放置__declspec((dllexport))或__attribute((dllexport))来更改此行为(即,如果指定要导出单个符号,则只有符号声明导出导出).如果库中存在大量符号,则在dll加载时可以显着提高性能.

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

所以是的,使用dllexport来防止.dll导出世界.

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

阅读文档时要小心;它实际上说的是当你使用dllexport属性时,它还会触发可见性:默认行为,除非它被覆盖.

上一篇:读书笔记 《Effective modern C++》之 Deducing Types & auto(一)


下一篇:_declspec(dllexport)和.def(转)