[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