ยปCore Development>Code coverage>PC/frozen_dllmain.c

Python code coverage for PC/frozen_dllmain.c

#countcontent
1n/a/* FreezeDLLMain.cpp
2n/a
3n/aThis is a DLLMain suitable for frozen applications/DLLs on
4n/aa Windows platform.
5n/a
6n/aThe general problem is that many Python extension modules may define
7n/aDLL main functions, but when statically linked together to form
8n/aa frozen application, this DLLMain symbol exists multiple times.
9n/a
10n/aThe solution is:
11n/a* Each module checks for a frozen build, and if so, defines its DLLMain
12n/a function as "__declspec(dllexport) DllMain%module%"
13n/a (eg, DllMainpythoncom, or DllMainpywintypes)
14n/a
15n/a* The frozen .EXE/.DLL links against this module, which provides
16n/a the single DllMain.
17n/a
18n/a* This DllMain attempts to locate and call the DllMain for each
19n/a of the extension modules.
20n/a
21n/a* This code also has hooks to "simulate" DllMain when used from
22n/a a frozen .EXE.
23n/a
24n/aAt this stage, there is a static table of "possibly embedded modules".
25n/aThis should change to something better, but it will work OK for now.
26n/a
27n/aNote that this scheme does not handle dependencies in the order
28n/aof DllMain calls - except it does call pywintypes first :-)
29n/a
30n/aAs an example of how an extension module with a DllMain should be
31n/achanged, here is a snippet from the pythoncom extension module.
32n/a
33n/a // end of example code from pythoncom's DllMain.cpp
34n/a #ifndef BUILD_FREEZE
35n/a #define DLLMAIN DllMain
36n/a #define DLLMAIN_DECL
37n/a #else
38n/a #define DLLMAIN DllMainpythoncom
39n/a #define DLLMAIN_DECL __declspec(dllexport)
40n/a #endif
41n/a
42n/a extern "C" DLLMAIN_DECL
43n/a BOOL WINAPI DLLMAIN(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
44n/a // end of example code from pythoncom's DllMain.cpp
45n/a
46n/a***************************************************************************/
47n/a#include "windows.h"
48n/a
49n/astatic char *possibleModules[] = {
50n/a "pywintypes",
51n/a "pythoncom",
52n/a "win32ui",
53n/a NULL,
54n/a};
55n/a
56n/aBOOL CallModuleDllMain(char *modName, DWORD dwReason);
57n/a
58n/a
59n/a/*
60n/a Called by a frozen .EXE only, so that built-in extension
61n/a modules are initialized correctly
62n/a*/
63n/avoid PyWinFreeze_ExeInit(void)
64n/a{
65n/a char **modName;
66n/a for (modName = possibleModules;*modName;*modName++) {
67n/a/* printf("Initialising '%s'\n", *modName); */
68n/a CallModuleDllMain(*modName, DLL_PROCESS_ATTACH);
69n/a }
70n/a}
71n/a
72n/a/*
73n/a Called by a frozen .EXE only, so that built-in extension
74n/a modules are cleaned up
75n/a*/
76n/avoid PyWinFreeze_ExeTerm(void)
77n/a{
78n/a // Must go backwards
79n/a char **modName;
80n/a for (modName = possibleModules+Py_ARRAY_LENGTH(possibleModules)-2;
81n/a modName >= possibleModules;
82n/a *modName--) {
83n/a/* printf("Terminating '%s'\n", *modName);*/
84n/a CallModuleDllMain(*modName, DLL_PROCESS_DETACH);
85n/a }
86n/a}
87n/a
88n/aBOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
89n/a{
90n/a BOOL ret = TRUE;
91n/a switch (dwReason) {
92n/a case DLL_PROCESS_ATTACH:
93n/a {
94n/a char **modName;
95n/a for (modName = possibleModules;*modName;*modName++) {
96n/a BOOL ok = CallModuleDllMain(*modName, dwReason);
97n/a if (!ok)
98n/a ret = FALSE;
99n/a }
100n/a break;
101n/a }
102n/a case DLL_PROCESS_DETACH:
103n/a {
104n/a // Must go backwards
105n/a char **modName;
106n/a for (modName = possibleModules+Py_ARRAY_LENGTH(possibleModules)-2;
107n/a modName >= possibleModules;
108n/a *modName--)
109n/a CallModuleDllMain(*modName, DLL_PROCESS_DETACH);
110n/a break;
111n/a }
112n/a }
113n/a return ret;
114n/a}
115n/a
116n/aBOOL CallModuleDllMain(char *modName, DWORD dwReason)
117n/a{
118n/a BOOL (WINAPI * pfndllmain)(HINSTANCE, DWORD, LPVOID);
119n/a
120n/a char funcName[255];
121n/a HMODULE hmod = GetModuleHandleW(NULL);
122n/a strcpy(funcName, "_DllMain");
123n/a strcat(funcName, modName);
124n/a strcat(funcName, "@12"); // stdcall convention.
125n/a pfndllmain = (BOOL (WINAPI *)(HINSTANCE, DWORD, LPVOID))GetProcAddress(hmod, funcName);
126n/a if (pfndllmain==NULL) {
127n/a /* No function by that name exported - then that module does
128n/a not appear in our frozen program - return OK
129n/a */
130n/a return TRUE;
131n/a }
132n/a return (*pfndllmain)(hmod, dwReason, NULL);
133n/a}
134n/a