[xsd-users] Linker problem caused by using std::ifstream/std::ofstream/std::fstream together with xsd::cxx::tree::string

Boris Kolpackov boris at codesynthesis.com
Tue Oct 5 10:26:56 EDT 2021


Krzynowek, Marek (CWM-NR) <marek.krzynowek at rbccm.com> writes:

> In our solution we have a DLL project, and in that project we have a file,
> let's call it utils.cpp, which includes xml_schema.hxx [...]
> 
> xml_schema.hxx starts with a comment:
> // Copyright (c) 2005-2014 Code Synthesis Tools CC
> //
> // This program was generated by CodeSynthesis XSD, an XML Schema to
> // C++ data binding compiler.
> 
> and at the end it contains lines:
> namespace xsd
> {
>   namespace cxx
>   {
>     namespace tree
>     {
>       template class XML_SCHEMA_API simple_type< char, ::xml_schema::Type >;
>       template class XML_SCHEMA_API string< char, ::xml_schema::SimpleType >;
>       template class XML_SCHEMA_API normalized_string< char, ::xml_schema::String >;
>       template class XML_SCHEMA_API token< char, ::xml_schema::NormalizedString >;
>       template class XML_SCHEMA_API name< char, ::xml_schema::Token >;
>       template class XML_SCHEMA_API nmtoken< char, ::xml_schema::Token >;
>       ...
>     }
>   }
> }
>
> #ifdef _MSC_VER
>    #if defined( BASE_XML_EXPORTS  )
>       # define XML_SCHEMA_API __declspec(dllexport)
>       [...]
>    #else
>       # define XML_SCHEMA_API __declspec(dllimport)
>    #endif // msc compiler
> #else
>     #define XML_SCHEMA_API    
> #endif
>
> The linker issue arises when our utils.cpp includes xml_schema.hxx AND
> creates an instance of either std::ifstream or std::ofstream or
> std::fstream. More specifically, it looks like it has something to
> do with xsd::cxx::tree::string inheriting from std::basic_string.

Ok, let me describe the underlying problem so that we hopefully have
an idea about what's going on here:

1. XSD built-in types (e.g., xml_schema::string) derive from std::string
   (this is done so that you can "seamlessly" pass xml_schema::string
   where std::string is expected).

2. In VC++, when you export a class (xml_schema::string in our case,
   caused by the --export-xml-schema option), it automatically exports
   the base class. So in our case std::string (aka std::basic_string)
   gets exported as well. There doesn't seem to be any way to disable
   exporting of or "unexport" a base class in VC++.

3. When you build your executable (or another DLL), there could be some
   source files that include "xml-schema.hxx" and therefore "see"
   std::string as imported from the DLL. In this case, you need to make
   sure to link the DLL where xml-schema.hxx exports its symbols (i.e.,
   where XML_SCHEMA_API is defined as __declspec(dllexport)).

Here are some previous post on the same topic, as a reference:

http://www.codesynthesis.com/pipermail/xsd-users/2010-September/003011.html

https://www.codesynthesis.com/pipermail/xsd-users/2010-September/003019.html



More information about the xsd-users mailing list