[xsd-users] Issue with using xsd generated code in DLLs with Visual Studio 2010

Boris Kolpackov boris at codesynthesis.com
Thu Sep 23 12:37:12 EDT 2010


Hi Timo,

Boris Kolpackov <boris at codesynthesis.com> writes:

> Are the clashing symbols in the leaf DLL also exported?

Ok, I played a bit with the test project that you sent me off-list.
Here is what I found:

The setup:

1. root.h in root.dll defines and exports class root that inherits
   from base<char>

2. leaf.h in lead.dll defines and exports class leaf that inherits
   from base<char>; leaf.dll links root.dll

3. private.cpp in leaf.dll uses base<char> without exporting it

The findings:

1. If leaf.h does not include root.h then we get symbol clashes.
   This is not really surprising since both root.dll and leaf.dll
   export base<char> symbols.

2. If private.cpp does not include root.h we also get symbol clashes.
   This is somewhat surprising to me since we normally expect the
   C++ compilation system to weed out duplicate symbols resulting
   from template instantiations. But it appears that the MS tool-
   chain only does this if both symbols are not exported. If at
   least one of them is exported, we get symbol clashes.

   What is even more surprising is that this appears to work when
   linking an executable. If we have private.cpp in an executable
   that links to root.dll, there are no symbol clashes.

3. If we include root.h in leaf.h prior to defining class leaf,
   then root.h sees it as imported from root.dll and uses that
   symbol instead of instantiating its own. In other words,
   the MS toolchain will automatically export unexported base
   class *unless* it is imported. This is expected.

4. Similarly, if we include root.h in private.cpp prior to using 
   base<char> then the same thing happens, no symbol clashes.

Now, how does this apply to the XSD-generated types? The types in the 
XML Schema namespace derive from std::basic_string<char> which can
cause this problem. The way to resolve this is to place these types
into the root DLL and export them so that we have a setup similar to
the one described above. I have listed the steps needed to achieve
this in one of my earlier emails. The important part here is that
all other DLLs (leaf DLLs) that contain XSD-generated code must 
use the --extern-xml-schema option when compiling the schemas.
If even one schema is compiled without this option, the whole
thing will break up.

Now we have two possible situations: leaf.dll has other classes
that it exports that also inherit from std::basic_string<char> 
(note that this cannot be XSD-generated code if --extern-xml-schema
was used consistently). Or it doesn't.

In the former case we will have to include the xml-schema.hxx
header into the header files defining such classes. Ugly but
seems the only way (well, actually, one can create a special
header or even a DLL that just exports std::basic_string<char>
and use that instead of xml-schema.hxx). 

In the latter case we need to include xml-schema.hxx into every
.cpp file that uses std::string. If the project uses precompiled
headers, stdafx.h is a good place to do this. This case is less
ugly since the xml-schema.hxx inclusion is the DLL's implementation
details.

Boris



More information about the xsd-users mailing list