1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
// **************************************************************************
#define WIN32_LEAN_AND_MEAN
#include <zen/win.h>
#include "init_dll_binding.h"
/*
http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx
"DllMain is called while the loader-lock is held. [...] You cannot call any function in
DllMain that directly or indirectly tries to acquire the loader lock. Otherwise, you will
introduce the possibility that your application deadlocks or crashes."
it's even worse: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
"If your DLL is linked with the C run-time library (CRT), the entry point provided by the CRT calls the constructors
and destructors for global and static C++ objects. Therefore, these restrictions for DllMain also apply to constructors
and destructors and any code that is called from them."
Example: http://blog.barthe.ph/2009/07/30/no-stdlib-in-dllmai/
Empirical study on DLL initialization order
-------------------------------------------
I. statically linked DLL:
DLL, static object constructors
DLL, DllMain(): DLL_PROCESS_ATTACH
main thread, static object constructors
main thread, enter main()
DLL, DllMain(): DLL_THREAD_ATTACH
DLL, DllMain(): DLL_THREAD_DETACH
main thread, exit main()
main thread, static object destructors
DLL, DllMain(): DLL_PROCESS_DETACH
DLL, static object destructors
II. dynamically linked DLL (living in main()):
main thread, static object constructors
main thread, main(): LoadLibrary
DLL, static object constructors
DLL, DllMain(): DLL_PROCESS_ATTACH
main thread, main(): FreeLibrary
DLL, DllMain(): DLL_PROCESS_DETACH
DLL, static object destructors
main thread, static object destructors
*/
//optional: add init/teardown logic here
BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
if (!findplus::initDllBinding())
return false;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return true;
}
|