diff -r 0659d0e1a03c -r 1d28c8722707 kerneltest/e32test/dll/t_nestdll.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/dll/t_nestdll.cpp Tue Nov 02 15:29:23 2010 +0000 @@ -0,0 +1,91 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\dll\t_nestdll.cpp +// +// + +#include +#include +#include + +// Utility macros for stringification, long-stringification, and token pasting +// These are indirected so that if you call them on things which are also macros, +// the macros are expanded first. +#define STRINGIFY_(x) #x +#define STRINGIFY(x) STRINGIFY_(x) +#define LSTRINGIFY_(x) L ## #x +#define LSTRINGIFY(x) LSTRINGIFY_(x) +#define PASTE_(x,y) x ## y +#define PASTE(x,y) PASTE_(x,y) + +// Declare the imported functions for the DLLs we statically link to +#ifdef LINK_TO +IMPORT_C TInt PASTE(DataForDLL,LINK_TO)(); +#endif + +// Dummy class just to get a constructor into the binary +class ConstructorTest + { +public: + ConstructorTest(); + }; + +// Constructor, which should be called exactly once per DLL +ConstructorTest::ConstructorTest() + { + RDebug::Printf("In constructor for DLL " STRINGIFY(DLL_NUMBER)); + + // Call the imported functions for the DLL we statically link to. + // This is just to get them into the import table. +#ifdef LINK_TO + PASTE(DataForDLL,LINK_TO)(); +#endif + + // Use DLL TLS handle zero to fake a global data object + TInt* loadOrder = (TInt*)UserSvr::DllTls(0); + if (!loadOrder) + { + // If we're the first constructor, allocate an array and zero it + loadOrder = new TInt[100]; + for (TInt i = 0; i < 100; ++i) + loadOrder[i] = 0; + UserSvr::DllSetTls(0, loadOrder); + } + + // Find the first zero entry in the load order array and add our index + TInt next = 0; + while (loadOrder[next] != 0) + ++next; + loadOrder[next] = DLL_NUMBER; + + // If we're supposed to be doing a nested DLL load, do it here. + // You aren't supposed to leave in a constructor but it causes an + // identifiable panic, to distinguish it from any other possible crash. +#ifdef LOAD_DLL + RDebug::Printf("Doing nested DLL load"); + RLibrary lib; + TInt r = lib.Load(TPtrC16((const TText*)(L"t_nestdll" LSTRINGIFY(LOAD_DLL) L".dll"))); + RDebug::Printf("Nested DLL load returned %d", r); + User::LeaveIfError(r); +#endif + } + +// Global instance of the dummy object +ConstructorTest constructor_test; + +// The exported function for this DLL, which just tells you how many times the constructor was called +EXPORT_C TInt PASTE(DataForDLL,DLL_NUMBER)() + { + return 0; + }