Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ [[gnu::visibility("default")]] vs __declspec(dllexport) on Windows and 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();

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?

like image 289
Szőke Szabolcs Avatar asked Jan 24 '14 14:01

Szőke Szabolcs


People also ask

What does __ Declspec Dllexport do?

__declspec(dllexport) adds the export directive to the object file so you do not need to use a . def file. This convenience is most apparent when trying to export decorated C++ function names.

What is Dllexport C++?

The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. You can use them to export and import functions, data, and objects to or from a DLL.

What is Declspec?

Microsoft Specific The extended attribute syntax for specifying storage-class information uses the __declspec keyword, which specifies that an instance of a given type is to be stored with a Microsoft-specific storage-class attribute listed below.

What does Fvisibility hidden do?

Parts of LLVM are compiled with -fvisibility=hidden . This option forces the default visibility of all symbols to be hidden , which prevents them from being visible across library boundaries. Hiding symbols offers better control over exported symbols in a shared library.


1 Answers

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.

like image 180
Petesh Avatar answered Sep 25 '22 02:09

Petesh