Windows和Linux上的C ++ [[gnu :: visibility("default")]]与__declspec(dllexport) [英] C++ [[gnu::visibility("default")]] vs __declspec(dllexport) on Windows and Linux

查看:337
本文介绍了Windows和Linux上的C ++ [[gnu :: visibility("default")]]与__declspec(dllexport)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I needed to make some shared libraries in C++ and I used linux as my developer operating system. I know that I need to make symbols visible if I want to load them via dlsym/LoadLibrary. So in linux all of my symbols followed this pattern:

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)吗?

I used clang with C++11 enabled and I was able to load f in my host program. When I moved to windows I used GCC 4.8.2 with C++11 enabled and that pattern worked on windows machine too with LoadLibrary. (I needed to use C++11 for new attribute syntax). I know that on windows I need to use __declspec(dllexport) to export symbols from shared library. So what now? Is __declspec(dllexport) not required anymore?

我在此处那些是同义词(我认为),所以问题是__declspec(dllimport)是否有[[gnu::attribute]]以避免使用宏,而ifdef则用于特定目标?

I found here that those are synonyms (I think) so the question is that is there an [[gnu::attribute]] for __declspec(dllimport) to avoid using macros and ifdefs for specific targets?

推荐答案

符号可见性与dllexport完全不同-主要原因是当您在Windows中的mingw/cygwin下编译.dll时,默认链接器的行为是选项-export-all-symbols-即默认情况下它将自动从您的.dll导出一切.

Symbol visibility is subtly different from dllexport - and the primary reason is that when you compile a .dll in Windows under mingw/cygwin, the default behaviour of the linker is the option -export-all-symbols - i.e. it will auto-export everything from your .dll by default.

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

You can change this behaviour by either using a .def file or putting either __declspec((dllexport)) or __attribute((dllexport)) on any routine (i.e. if you specify that a single symbol is to be exported then only the symbols that are declared exported are exported). This can have a significant performance improvement at dll load time if there are a lot of symbols in your library.

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

If you want to use the equivalent C++ attribute, then you use [[gnu::dllexport]]

是的,请使用dllexport阻止.dll导出世界.

So yes, use dllexport to keep your .dll from exporting the world.

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

In a similar manner you can use [[gnu:dllimport]] for importing external routines.

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

Careful while reading the documentation; what it actually says is that when you use the dllexport attribute, it also triggers the visibility:default behaviour unless it's overridden.

这篇关于Windows和Linux上的C ++ [[gnu :: visibility("default")]]与__declspec(dllexport)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆