Sign in to follow this  
tron_thomas

Different variable used with static template method from DLL

Recommended Posts

I am trying to design a template class that can implement a class factory. The class factory will exist in and be exported from a DLL (on Windows) or a shared library (on Linux/Mac OS X). To deal with linkage and storage issues Windows DLL the following file is defined: -- Linkage.h -- #ifndef __LINKAGE_H__ #define __LINKAGE_H__ #ifdef WIN32 #ifdef CLASSFACTORY_DLL #define LINKAGE __declspec(dllexport) #define STORAGE #else #define LINKAGE __declspec(dllimport) #define STORAGE extern #endif // def CLASSFACTORY_DLL #else #define LINKAGE #define STORAGE #endif // def WIN32 #endif // ndef __LINKAGE_H__ The class factory template is then define like this: -- ClassFactory.h -- #ifndef __CLASSFACTORY_H__ #define __CLASSFACTORY_H__ #include "Linkage.h" #include <map> #include <sstream> #include <stdexcept> template <typename Key, typename Base, typename Compare = std::less<Key> > class LINKAGE ClassFactory { private: typedef Base* (*CreatorFunction)(void*); typedef std::map<Key, CreatorFunction, Compare> FactoryMap; public: static Key RegisterCreatorFunction ( Key key, CreatorFunction creator ) { GetMap()[key] = creator; return key; } static Base* CreateInstance ( Key key, void* data = NULL ) { using std::stringstream; using std::runtime_error; FactoryMap& factoryMap = GetMap(); typename FactoryMap::iterator factoryPair = factoryMap.find(key); if(factoryMap.end() == factoryPair){ stringstream stream; stream << "Cannot find a creator function for key " << key << '.'; throw runtime_error(stream.str()); } if(NULL == factoryPair->second){ stringstream stream; stream << "No creator function defined for key " << key << '.'; throw runtime_error(stream.str()); } return factoryPair->second(data); } private: static FactoryMap& GetMap() { static FactoryMap factoryMap; return factoryMap; } }; #endif // ndef __CLASSFACTORY_H__ Finally, the DLL will include a source file that specifies a particular class factory to export like this: #include "Linkage.h" #include "ClassFactory.h" #include <string> class LINKAGE SomeBaseObject { public: virtual ~SomeBaseObject(){}; }; STORAGE template ClassFactory<std::string, SomeBaseObject>; typedef ClassFactory<std::string, SomeBaseObject> SomeBaseObjectFactory; There will also be some objects in the DLL that will register with the class library so they can be created at run time. All of this work just fine on Linux and Mac OS X. However on Windows it fails. Setting breakpoints in the class factory header file reveal that a totally different factoryMap variable is used when object are register than when objects are create through the CreateInstance method. This means the factoryMap variable for CreateInstance has no data, and so all attempts to create objects fail. What is needed so the same variable is used in both situations so the class factory can work as expected?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this