--- /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 <e32std.h>
+#include <e32debug.h>
+#include <e32svr.h>
+
+// 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;
+ }