MSVC: handle symbol visibility

On MSVC, the exported symbols have to be marked both in the header and
in the implementation as dllexport, whereas on GCC the visibility=normal
attribute is only supposed to be used in the implementation. As a
result, we need two types of macros here, one for the public headers,
and the other for TUs with implementation. Also, the symbol name cannot
be generic ("API") because we only want to mark as dllexport those
symbols which are in a library that we're building *now*. Otherwise this
will break havoc in any libraries which also use the `ABI` macro *and*
also use libyang.
diff --git a/src/config.h.in b/src/config.h.in
index de9c40c..9915a83 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -35,4 +35,28 @@
 # define _FORMAT_PRINTF(FORM, ARGS)
 #endif
 
+/** Exporting symbols to a shared library and importing back afterwards
+ *
+ * - use LIBYANG_API_DECL to mark a declaration in the public header
+ * - use LIBYANG_API_DEF to mark a definition (in the source code for the actual implementaiton)
+ * */
+#ifdef _MSC_VER
+#  ifndef STATIC
+#    define LIBYANG_API_DEF __declspec(dllexport)
+#    ifdef LIBYANG_BUILD
+#      define LIBYANG_API_DECL __declspec(dllexport)
+#    else
+#      define LIBYANG_API_DECL __declspec(dllimport)
+#    endif
+#  endif
+#else
+/*
+ * If the compiler supports attribute to mark objects as hidden, mark all
+ * objects as hidden and export only objects explicitly marked to be part of
+ * the public API.
+ */
+#  define LIBYANG_API_DEF __attribute__((visibility("default")))
+#  define LIBYANG_API_DECL
+#endif
+
 #endif /* LY_CONFIG_H_ */