Clang 是否可以在使用可见性属性时生成导入库(不带 __declspec(dllexport))?

Can Clang generate an import library when using the visibility attribute (without __declspec(dllexport))?

本文关键字:导入 不带 declspec dllexport 是否 属性 可见性 Clang      更新时间:2023-10-16

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

class __declspec(dllexport) Foo {};

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

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

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

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

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

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

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

将 DLL 与 MS link.exe 或 LLVM 的 lld-link(模仿 link.exe 的行为)链接时,仅导出标有__declspec(dllexport)或传递到链接器的 def 文件中列出的符号。

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

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

除了@mstorsjo的答案之外,这里有一个将 def 文件传递给 clang 的示例。

clang -shared structs.c -o structs.dll -Wl"/DEF:structs.def"

我为此挣扎了一天,希望它对某人有所帮助(解释)