首页 > 解决方案 > 使用可见性属性(没有 __declspec(dllexport))时,Clang 可以生成导入库吗?

问题描述

使用 Microsoft 编译器时,要从库中导出类或函数,您将使用类似于以下内容的代码:

class __declspec(dllexport) Foo {};

使用 Clang(和 GCC),您可以使用 visibility 属性来确保符号可见:

class __attribute__((visibility(default))) Foo {};

或者依赖于编译时设置的可见性。

当我在 Windows 上使用 Clang 编译时,如果一个类可见(即使具有显式属性),则不会导出该函数(不创建导入库)。

是否可以让 Clang 在不使用__declspec(dllexport)Clang主要但不完全支持的 Microsoft 扩展的情况下生成导入库。

标签: c++windowsdllclang

解决方案


澄清一些事情;生成导入库的不是编译器(Clang)本身,而是链接器,而目标文件格式在此过程中起着重要作用。

调整导出的符号__attribute__((visibility(default)))(当使用 将其他符号标记为隐藏时__attribute__((visibility(hidden))),或使用类似的设置默认值时-fvisibility=hidden,在构建 ELF 对象文件时与 GCC 和 Clang 一起使用。COFF 没有类似的每个符号可见性标志。

当使用 MS link.exe 或 LLVM 的 lld-link(模仿 link.exe 的行为)链接 DLL 时,只会导出标有__declspec(dllexport)或在传递给链接器的 def 文件中列出的符号。

在 MinGW 生态系统中(带来更多类似 unix 的行为),如果没有明确选择符号,则默认导出所有全局符号(使用一些逻辑以避免导出属于 mingw 基础库本身的东西)要出口。

如果使用 lld-link 而不是 MS link.exe 链接(通过调用 lld-link 而不是链接,如果直接调用链接器,或者-fuse-ld=lld如果通过 clang-cl 前端调用链接器则添加),您可以选择加入通过添加 lld 特定选项来实现行为,该选项在 lld-lldmingw中启用了许多 MinGW 特定的行为。


推荐阅读