>>1
The C standard defines linkage with respect to a single program. The standard does not define the mechanics on which the linkage operates, but most systems implement the process in a similar fashion. Thus, let us refer to that sort of linkage as "static", since they're determined at link-time.
Dynamic linking libraries (DLLs) in Windows and shared objects (SOs) in Linux are possible through the mechanism of "dynamic linkage". They're opposed to the "static linkage" defined in C in the sense that they cannot be determined at link-time, but rather at run-time.
Therefore, with respect to this new form of linkage, symbols can be either internal or external, pretty much like symbols can be
extern or
static in C jargon. The terms used are "imported" symbols (when a symbol is explicitly said to be loaded from another module) and "exported" symbols (when a symbol is explicitly said to be accessible to other modules).
Because the language does not define dynamic linkage, compilers support extensions with help programmers select symbols for dynamic linking.
__declspec(dllexport) and
__declspec(dllimport) are MSVC extensions used directly in the source code to indicate dynamic linkage. Definition (.def) files can be provided to the linker to achieve the same effect. In the GCC toolchain, visibility attributes (which are intended to manipulate ELF's symbol visibilities) also work the same way when the linker is outputting a PE image.
There is an important difference between the MSVC and the GCC toolchain (or rather, between ELF and PE images). By default, every symbol is "hidden" (that is, no external linkage) for PE targets. However, in ELF targets, by default every symbol with external linkage is default-visible. This means that no extra keywords are necessary when compiling ELFs, but they're needed when compiling PEs.
This also means that most sensible library developers will yield
-fvisibility=hidden in their GCC command-lines, to turn off the retarded default scheme which raises library load times unnecessarily and exposes internals which can lead to bugs and security holes.
Also, you can do the same to variables, of course. They're just symbols. Besides the name,
GetProcAddress() will return an address which can refer to a variable or anything the linker happened to put under that symbol entry, which can even be artificial (hard-valued) addresses.
Take a look at
man etext.