3

I do a lot of programming in linux and I use the visibility attribute to define if a symbol is visible or hidden in the Shared Object. Just to make the things clearer possible: If a symbol is visible it will be accessible externally (someone linking with the shared object), if it is hidden it is supposed to be used only internally.

On windows it seems to work a bit different, it works with exporting (the symbol is defined here in the shared object and will be accessible by someone linking with this) and importing (here I am linking with a shared object and the symbol is exported there) symbols. But I couldn't find a way to tell the compiler to not export a symbol because it must be used only here, i.e. if someone link with it a linker error is expected.

My question is if I can define a symbol as "hidden" (like in linux's gcc) and how. Also, all this visibility in windows topic is a bit fuzzy for me and I was looking for some further reading links to understand better how everything works.

André Puel
  • 8,741
  • 9
  • 52
  • 83

1 Answers1

7

David Rodriguez is correct, in the MSVC environment the programmer typically explicitly exports function/class symbols via the MSVC-specific __declspec(dllexport) modifier. Symbols that aren't explicitly exported shouldn't show up in the symbol table for the compiled DLL (you can use dumpbin, one of the Visual Studio command line utils, to verify, using the /EXPORTS option). It is convention to use dllimport when you import that symbol, although I believe this is optional. How this typically plays out is that header files defining the public interface of a DLL will have some macro that expands to __declspec(dllimport) by default, but is set to expand to __declspec(dllexport) while that library is being built.

Note that how GCC and MSVC treat dllexport may be different; perhaps GCC doesn't 'respect' dllexport in the sense of hiding unexported symbols? I would first try compiling with MSVC and test those results with dumpbin before trying the same with GCC. If you don't have Visual Studio, you can still get a MSVC compiler by either downloading VS Express, or (less known) by downloading certain .NET redistributables which ship with command line MSVC (both these options are free and legit). VS Express may be the better choice here so you can get dumpbin.

WeirdlyCheezy
  • 704
  • 4
  • 4
  • Under MSVC you can also export via module definition file (.def) , at which point the declspecs() can be thrown entirely under the bus (and depending on the build settings, *have* to be). – WhozCraig Oct 03 '12 at 23:39
  • @WhozCraig Haven't used .def much before, but I believe you are correct. The library author(s) make the choice between these two methods, so the existence of .def as an option hopefully doesn't prevent the op from choosing dllexport and using it to semi-effectively limit visibility under MSVC. – WeirdlyCheezy Oct 03 '12 at 23:41
  • Totally. I have found in the past that defining specific exposed entries in DLL's under Windows is *so* much cleaner than Linux simply because the default exposure is none at all, but I spend more time with one than the other, so that undoubtedly jades my opinion on the matter. – WhozCraig Oct 03 '12 at 23:45
  • 3
    @WhozCraig Just use `-fvisibility=hidden` as a command line switch for GCC or Clang and you have exactly the same behavior on Linux/UNIX/MacOS X: Nothing is exported, unless you either export it by defining a different visibility in your code or place the symbol into a symbol file that you pass to the compiler/linker. – Mecki Jun 11 '13 at 14:56
  • @Mecki Thank you SO much for that. I really need to spend more time on the option-charts of gcc. – WhozCraig Jun 11 '13 at 16:58