0

I know, it may seem strange, but my goal is to undefine a class in C++. The root of the problem is in combining TinyXML2 and Boost unit tests.

Contents of the header file (Configuration.h) which is being tested:

...
#include <tinyxml2.h>
...

And this is the contents of my configurationTests.h file:

#include "unitTests.h"
#include "Configuration.h"

BOOST_AUTO_TEST_SUITE(configuration_test)

BOOST_AUTO_TEST_CASE(basic) {
    ...
}

BOOST_AUTO_TEST_SUITE_END( )

When I try to compile my tests, I'm getting an error:

error C2371: 'XMLDocument' : redefinition; different basic types c:\program files (x86)\windows kits\8.0\include\um\msxml.h 10085

Inside this file (msxml.h) on line 10085 we have this class definition:

class DECLSPEC_UUID("CFC399AF-D876-11d0-9C10-00C04FC99C8E")
XMLDocument;

When I remove those two lines, my tests do compile and everything seems fine. Of course, this is not a solution, but that fact prooves that something inside Boost unit tests library includes msxml.h and somehow leads to conflict with TinyXML2 library.

I tried different solutions found in Google (like writing "#define WIN32_LEAN_AND_MEAN"), removing "using namespace tinyxml2" and making changes inside tinyxml2.cpp - nothing actually helps.

So, my question is simple: can I undefine (unload?) previously defined class in compile time in some tricky way? I tried "#undef XMLDocument", "#define XMLDocument 1" + "#undef XMLDocument" - nothing works.

Update: Actually, I kinda solved the problem by writing "#define MSXML_LIBRARY_DEFINED" on the first line of configurationTests.h. But still, I would love to know an answer to this topic question.

Cruel_Crow
  • 359
  • 3
  • 15
  • I might have run into a similar problem. I started to use Boost.Test and the tests I saw when running my Boost.Test project were from TinyXML's `xmltest.cpp`, which was really confusing. Do you know why Boost.Test is finding TinyXML's tests? – Derek Aug 13 '15 at 13:38

2 Answers2

1

I think you have used default namespace for tinyxml2. Try to delete using namespace tinyxml2 and then use it like in this example: tinyxml2::XMLDocument xDoc;

ElGovanni
  • 106
  • 1
  • 10
0

try this:

namespace your_name_space 
{
    #include <tinyxml2.h>
}

From now all classes inside the tinyxml2 are hidden by your namespace.

The namespece must be declared also for the tinyxml2.cpp file.

AngeloDM
  • 397
  • 1
  • 8
  • Note that this only has a chance of working well if tinyxml is a C-only interface, and/or doesn't include any new files, and/or is header only to begin with. I've done this with libcurl, e.g. but if it weren't using `extern "C"` in the header, it would never have worked. This is a dangerous strategy in that respect. Then again, all resolutions in the end would come down to similar drudgery – sehe Apr 05 '14 at 22:22
  • You are right, that depends by internal implementation of the tinyxml2.h, do you suggest me to delete answer? or this solution could be used in other context?. – AngeloDM Apr 05 '14 at 22:39
  • Nah, I'm just providing some depth to the answer. Let the OP decide whether this convenes him/her – sehe Apr 05 '14 at 22:47
  • It doesn't seem to help. Which, I agree, is actually strange. Plus, this solution, even if worked, actually forcing me to rewrite my original code, while the problem itself is in a small test file. By the way, TinyXML is fully C++ library, not C. – Cruel_Crow Apr 06 '14 at 11:04