00001 #pragma once 00002 00003 //////////////////////////////////////////////////////////////////////////////// 00004 /// 00005 /// \file 00006 /// \author Gerald Fahrnholz 00007 /// 00008 /// \defgroup GrpTestInstanceDll Using TestInstanceDll 00009 /// @{ 00010 /// \ingroup GrpTestUtils 00011 /// \brief 00012 /// The Win32 DLL "TestInstanceDll.DLL" is responsible for creating and storing 00013 /// singleton instances of TestUtility objects. This is important when running a 00014 /// test environment which wants to make use of the test utilities also within some 00015 /// DLLs. 00016 /// 00017 /// <b>\n Motivation:</b> 00018 /// 00019 /// Most of the TestUtilities are used as singletons in order to give simple access 00020 /// to the same object from any piece of your test code. 00021 /// Per default the following simple singleton pattern is used: 00022 /// \code 00023 /// class TestEvents 00024 /// {... 00025 /// static TestEvents* Get (void) 00026 /// {if (!s_pTestEvents) s_pTestEvents = new TestEvents; 00027 /// return s_pTestEvents;} 00028 /// static TestEvents* s_pTestEvents; 00029 /// ...} 00030 /// \endcode 00031 /// 00032 /// This works well as long as you use the test utilities only within your main application. 00033 /// When making use of them also in user written DLL code the problem will arise, that each DLL 00034 /// gets its own singleton instance when calling TestEvents::Get(). 00035 /// In most cases this is not what you want. Usually you are interested to use singleton instances 00036 /// being unique within your whole Win32 process. 00037 /// 00038 /// <b>\n Solution:</b> 00039 /// 00040 /// Instead of storing simple static class members, instances are created and stored within 00041 /// the separate TestInstanceDLL. 00042 /// 00043 /// \n To leave the client code unaffected the access to the instance DLL is encapsulated 00044 /// in the Get() methods and the changed behaviour is activated via preprocessor define 00045 /// USE_TEST_INSTANCE_DLL: 00046 /// 00047 /// \code 00048 /// // file TestEvents.h: 00049 /// 00050 /// // Declaration of methods within TestInstanceDll 00051 /// #ifdef USE_TEST_INSTANCE_DLL 00052 /// # include "TestToolBox/TestInstanceDll.h" 00053 /// #endif 00054 /// 00055 /// class TestEvents 00056 /// {... 00057 /// #ifdef USE_TEST_INSTANCE_DLL 00058 /// static TestEvents* CreateNewInstanceForUsageInDll(void){return new TestEvents;}; 00059 /// static TestEvents* Get (void) 00060 /// {return TTB_GetInstance_TestEvents();} 00061 /// #else 00062 /// static TestEvents* Get (void) 00063 /// {if (!s_pTestEvents) s_pTestEvents = new TestEvents; 00064 /// return s_pTestEvents;} 00065 /// static TestEvents* s_pTestEvents; 00066 /// #endif 00067 /// ...} 00068 /// 00069 /// // Use static memeber only when running without TestInstanceDLL 00070 /// #ifndef USE_TEST_INSTANCE_DLL 00071 /// __declspec(selectany) TestEvents* TestEvents::s_pTestEvents = 0; 00072 /// #endif 00073 /// \endcode 00074 /// 00075 /// <b>\n Necessary steps for using TestUtilities within DLLs:</b> 00076 /// 00077 /// - generate TestInstanceDLL and / or create dependency of your test project from it 00078 /// - set define USE_TEST_INSTANCE_DLL within all your test projects 00079 /// - currently the test utilities are used as explicit classes (and not only via virtual 00080 /// member functions). Therefore all projects have to include the implementation code 00081 /// (e.g. TestEventsImpl.h) 00082 /// and/or link with the used test libraries. 00083 /// - access singleton instances via static class methods Get() (e.g. TestEvents::Get()); 00084 /// this is no difference compared to usage within a single main app! 00085 /// 00086 /// \sa TestInstanceDll.h (file documentation) 00087 /// \sa GrpTestEnvWithMultipleDlls (test app) 00088 /// 00089 //////////////////////////////////////////////////////////////////////////////// 00090 00091 /// \cond 00092 00093 #ifdef TESTINSTANCEDLL_EXPORTS 00094 #define TEST_INSTANCE_DLL_API __declspec(dllexport) 00095 #else 00096 #define TEST_INSTANCE_DLL_API __declspec(dllimport) 00097 #ifdef NDEBUG 00098 #pragma comment( lib, "TestInstanceDll" ) 00099 #else 00100 #pragma comment( lib, "TestInstanceDllD" ) 00101 #endif 00102 #endif 00103 00104 00105 namespace TestToolBox 00106 { 00107 class Environment; 00108 class TestEvents; 00109 class Synchronizer; 00110 } 00111 00112 00113 TEST_INSTANCE_DLL_API TestToolBox::Environment* TTB_GetInstance_Environment (void); 00114 TEST_INSTANCE_DLL_API void TTB_CleanupInstance_Environment (void); 00115 00116 TEST_INSTANCE_DLL_API TestToolBox::TestEvents* TTB_GetInstance_TestEvents (void); 00117 TEST_INSTANCE_DLL_API void TTB_CleanupInstance_TestEvents (void); 00118 00119 TEST_INSTANCE_DLL_API TestToolBox::Synchronizer* TTB_GetInstance_Synchronizer (void); 00120 TEST_INSTANCE_DLL_API void TTB_CleanupInstance_Synchronizer (void); 00121 00122 ///\endcond 00123 00124 ///@} // end group GrpTestInstanceDll