C++ [[gnu::visibility("default")]] vs __declspec(dllexport) on Windows and Linux
Asked Answered
F

1

7

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();

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?

Edit:

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?

Francinefrancis answered 24/1, 2014 at 14:59 Comment(0)
B
5

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.

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.

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

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

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

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.

Bozarth answered 9/9, 2014 at 13:34 Comment(2)
As I understand [[gnu::dllexport]] is for GCC only, isn't it? Is there anything like this, that works under Clang and MSVC too?Demonology
It'll work on clang as well. MSVC doesn't have the equivalent, so if you want code that's compatible across the board, you're likely going to have to resort to macros. All three compilers support the using __declspec((dllexport|dllimport)), so you could use that, but it's not 'clean' C++. You can only rely on the standard specified [[ ]] attributes if you want to guarantee platform compatible code.Bozarth

© 2022 - 2024 — McMap. All rights reserved.