17db96d56Sopenharmony_ci/* FreezeDLLMain.cpp 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciThis is a DLLMain suitable for frozen applications/DLLs on 47db96d56Sopenharmony_cia Windows platform. 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ciThe general problem is that many Python extension modules may define 77db96d56Sopenharmony_ciDLL main functions, but when statically linked together to form 87db96d56Sopenharmony_cia frozen application, this DLLMain symbol exists multiple times. 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ciThe solution is: 117db96d56Sopenharmony_ci* Each module checks for a frozen build, and if so, defines its DLLMain 127db96d56Sopenharmony_ci function as "__declspec(dllexport) DllMain%module%" 137db96d56Sopenharmony_ci (eg, DllMainpythoncom, or DllMainpywintypes) 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci* The frozen .EXE/.DLL links against this module, which provides 167db96d56Sopenharmony_ci the single DllMain. 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci* This DllMain attempts to locate and call the DllMain for each 197db96d56Sopenharmony_ci of the extension modules. 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci* This code also has hooks to "simulate" DllMain when used from 227db96d56Sopenharmony_ci a frozen .EXE. 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ciAt this stage, there is a static table of "possibly embedded modules". 257db96d56Sopenharmony_ciThis should change to something better, but it will work OK for now. 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ciNote that this scheme does not handle dependencies in the order 287db96d56Sopenharmony_ciof DllMain calls - except it does call pywintypes first :-) 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ciAs an example of how an extension module with a DllMain should be 317db96d56Sopenharmony_cichanged, here is a snippet from the pythoncom extension module. 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci // end of example code from pythoncom's DllMain.cpp 347db96d56Sopenharmony_ci #ifndef BUILD_FREEZE 357db96d56Sopenharmony_ci #define DLLMAIN DllMain 367db96d56Sopenharmony_ci #define DLLMAIN_DECL 377db96d56Sopenharmony_ci #else 387db96d56Sopenharmony_ci #define DLLMAIN DllMainpythoncom 397db96d56Sopenharmony_ci #define DLLMAIN_DECL __declspec(dllexport) 407db96d56Sopenharmony_ci #endif 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci extern "C" DLLMAIN_DECL 437db96d56Sopenharmony_ci BOOL WINAPI DLLMAIN(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 447db96d56Sopenharmony_ci // end of example code from pythoncom's DllMain.cpp 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci***************************************************************************/ 477db96d56Sopenharmony_ci#include "windows.h" 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_cistatic char *possibleModules[] = { 507db96d56Sopenharmony_ci "pywintypes", 517db96d56Sopenharmony_ci "pythoncom", 527db96d56Sopenharmony_ci "win32ui", 537db96d56Sopenharmony_ci NULL, 547db96d56Sopenharmony_ci}; 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ciBOOL CallModuleDllMain(char *modName, DWORD dwReason); 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci/* 607db96d56Sopenharmony_ci Called by a frozen .EXE only, so that built-in extension 617db96d56Sopenharmony_ci modules are initialized correctly 627db96d56Sopenharmony_ci*/ 637db96d56Sopenharmony_civoid PyWinFreeze_ExeInit(void) 647db96d56Sopenharmony_ci{ 657db96d56Sopenharmony_ci char **modName; 667db96d56Sopenharmony_ci for (modName = possibleModules;*modName;*modName++) { 677db96d56Sopenharmony_ci/* printf("Initialising '%s'\n", *modName); */ 687db96d56Sopenharmony_ci CallModuleDllMain(*modName, DLL_PROCESS_ATTACH); 697db96d56Sopenharmony_ci } 707db96d56Sopenharmony_ci} 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci/* 737db96d56Sopenharmony_ci Called by a frozen .EXE only, so that built-in extension 747db96d56Sopenharmony_ci modules are cleaned up 757db96d56Sopenharmony_ci*/ 767db96d56Sopenharmony_civoid PyWinFreeze_ExeTerm(void) 777db96d56Sopenharmony_ci{ 787db96d56Sopenharmony_ci // Must go backwards 797db96d56Sopenharmony_ci char **modName; 807db96d56Sopenharmony_ci for (modName = possibleModules+Py_ARRAY_LENGTH(possibleModules)-2; 817db96d56Sopenharmony_ci modName >= possibleModules; 827db96d56Sopenharmony_ci *modName--) { 837db96d56Sopenharmony_ci/* printf("Terminating '%s'\n", *modName);*/ 847db96d56Sopenharmony_ci CallModuleDllMain(*modName, DLL_PROCESS_DETACH); 857db96d56Sopenharmony_ci } 867db96d56Sopenharmony_ci} 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ciBOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 897db96d56Sopenharmony_ci{ 907db96d56Sopenharmony_ci BOOL ret = TRUE; 917db96d56Sopenharmony_ci switch (dwReason) { 927db96d56Sopenharmony_ci case DLL_PROCESS_ATTACH: 937db96d56Sopenharmony_ci { 947db96d56Sopenharmony_ci char **modName; 957db96d56Sopenharmony_ci for (modName = possibleModules;*modName;*modName++) { 967db96d56Sopenharmony_ci BOOL ok = CallModuleDllMain(*modName, dwReason); 977db96d56Sopenharmony_ci if (!ok) 987db96d56Sopenharmony_ci ret = FALSE; 997db96d56Sopenharmony_ci } 1007db96d56Sopenharmony_ci break; 1017db96d56Sopenharmony_ci } 1027db96d56Sopenharmony_ci case DLL_PROCESS_DETACH: 1037db96d56Sopenharmony_ci { 1047db96d56Sopenharmony_ci // Must go backwards 1057db96d56Sopenharmony_ci char **modName; 1067db96d56Sopenharmony_ci for (modName = possibleModules+Py_ARRAY_LENGTH(possibleModules)-2; 1077db96d56Sopenharmony_ci modName >= possibleModules; 1087db96d56Sopenharmony_ci *modName--) 1097db96d56Sopenharmony_ci CallModuleDllMain(*modName, DLL_PROCESS_DETACH); 1107db96d56Sopenharmony_ci break; 1117db96d56Sopenharmony_ci } 1127db96d56Sopenharmony_ci } 1137db96d56Sopenharmony_ci return ret; 1147db96d56Sopenharmony_ci} 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ciBOOL CallModuleDllMain(char *modName, DWORD dwReason) 1177db96d56Sopenharmony_ci{ 1187db96d56Sopenharmony_ci BOOL (WINAPI * pfndllmain)(HINSTANCE, DWORD, LPVOID); 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci char funcName[255]; 1217db96d56Sopenharmony_ci HMODULE hmod = GetModuleHandleW(NULL); 1227db96d56Sopenharmony_ci strcpy(funcName, "_DllMain"); 1237db96d56Sopenharmony_ci strcat(funcName, modName); 1247db96d56Sopenharmony_ci strcat(funcName, "@12"); // stdcall convention. 1257db96d56Sopenharmony_ci pfndllmain = (BOOL (WINAPI *)(HINSTANCE, DWORD, LPVOID))GetProcAddress(hmod, funcName); 1267db96d56Sopenharmony_ci if (pfndllmain==NULL) { 1277db96d56Sopenharmony_ci /* No function by that name exported - then that module does 1287db96d56Sopenharmony_ci not appear in our frozen program - return OK 1297db96d56Sopenharmony_ci */ 1307db96d56Sopenharmony_ci return TRUE; 1317db96d56Sopenharmony_ci } 1327db96d56Sopenharmony_ci return (*pfndllmain)(hmod, dwReason, NULL); 1337db96d56Sopenharmony_ci} 1347db96d56Sopenharmony_ci 135