[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