RE: [xml] Creating Win32 wrapper function for exported variables



Hopefully this will put this to rest...

Exporting data from a library requires an additional layer of indirection
because you have to go through the import address table.  This would make
ugly code because every exported variable would look like

#ifdef _DLL 
 int someVar;   /* when accessed from within the dll */
#else
 int *someVar;  /* when accessed outside the dll */
#endif

Obviously this is to be avoided at all costs.  Using __declspec(dllexport)
and __declspec(dllimport) handle the indirection automatically.

For our solution:  If we export data entirely through the .def file (not
using any LIBXML_DLL_IMPORTS macro) which also needs the tag DATA appended
to the variable names in the .DEF file, any program using wanting to use
this data in libxml2.dll (such as xmllint) needs to still declare the
variable with __declspec(dllimport) int someVar; --  Using extern int
someVar alone will not work as that will return a ptr to the value and not
the stored value.  This is a read only pointer and is why xmllint gets a
segv when built against libxml2_so.dsp and you use the --valid flag or using
--version.

So, regardless the libxml2 headers need have some win32 references and hence
we need to keep LIBXML_DLL_IMPORTS.  So here's my proposed solution:

1.  All functions are exported through the .DEF file as currently done.  
2.  All global variables that should be made available externally needed to
be declared in their implementation (.c) as LIBXML_DLL_IMPORT type name.  
3.  In the headers, they are declared as LIBXML_DLL_IMPORT extern type
variable.
4.  We need to change the definition of LIBXML_DLL_IMPORT.  When built as a
dynamic library (libxml2_so.dsp), an additional preprocessor defition of
LIBXML_EXPORTS is defined.  This is used to identify that we are building
libxml2, and not just linking against it.  When building the static library
(libxml2_a.dsp) it does not matter if LIBXML_EXPORTS is set or not.

So, in win32xmlversion.h et al we have
#ifndef LIBXML_DLL_IMPORT
#ifdef _WIN32
#ifdef LIBXML_EXPORTS
#define LIBXML_DLL_IMPORT __declspec(dllexport)
#else
#define LIBXML_DLL_IMPORT __declspec(dllimport)
#endif
#else
#define LIBXML_DLL_IMPORT
#endif
#endif

This cleans up a lot of linker warnings which people are always complaining
about and allows programs, such as xmllint to be built against libxml2_so
(which currently it cannot -- it will only work properly when linked against
libxml2_a.dsp).

I don't know about cgywin so any input there?







[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]