I ran into a confusing problem with DLL files created by CMake on Windows. In my library, I use the Curiously Recurring Template Pattern to give certain classes a unique ID:
// da/Attribute.h: #ifndef DA_ATTRIBUTE_H #define DA_ATTRIBUTE_H namespace da { typedef unsigned int AttributeId; class AttributeBase { public: virtual AttributeId getTypeId() const=0; protected: /** Static ID counter. Every class that derives da::AttributeBase is assigned an increment of this counter as its type ID number */ static AttributeId sNextId; }; template <class Derived> class Attribute : public AttributeBase { private: static AttributeId msTypeId; public: Attribute() { if (msTypeId == 0) { msTypeId = ++sNextId; } } virtual ~Attribute() { } /** For static contexts */ static AttributeId typeId() { if (msTypeId == 0) { msTypeId = ++sNextId; } return msTypeId; } AttributeId getTypeId() const { return typeId(); } }; template <class Derived> AttributeId Attribute<Derived>::msTypeId = 0; } #endif
The problem is that when I associate a DLL with an executable project, there are some inconsistencies with the various ID methods. For instance:
...
Starting with GDB with a break in Foo :: getTypeID (), I found that "msTypeId" and "Foo :: msTypeId" have different memory addresses. What the hell. p>
This only happens when Foo is defined in the DLL. (And only on Windows 7, apparently, I do not have this problem in my Debian build). If I create a derived class inside main.cpp or just compile all the code from the library into an executable file, skipping the DLL completely, it works without problems.
Everything was compiled using MSYS and MinGW, with GCC 4.7 in Windows 7 Home Premium.
Here's CMakeLists.txt for the library, in case I messed up something:
cmake_minimum_required(VERSION 2.6) project(foo) add_definitions(-std=c++0x) set(CMAKE_BUILD_TYPE Debug) set(sources Foo.cpp ) add_library(foo SHARED ${sources})
source share