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 ifdef
s for specific targets?
Symbol visibility is subtly different from
dllexport
- and the primary reason is that when you compile a.dll
in Windows undermingw
/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 thevisibility:default
behaviour unless it's overridden.