//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Динамические BPL's Load_Execute_Unload_Package (LEUP) // Загрузить bpl (если нужно) // Выполнить ??? // Выгрузить bpl (если был загружен) // // Магические символы, добавляемые к названию функции при записи в библиотеку // Для: // extern "C" __declspec(dllexport) void Name (void); "_Name" // // PACKAGE void __fastcall Name (void); "@Name$qqrv" // PACKAGE void __fastcall Name (int); "@Name$qqri" // PACKAGE void __fastcall Name (const int); "@Name$qqrxi" // PACKAGE void __fastcall Name (const long); "@Name$qqrxl" //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int __fastcall loc_LEUP_GetFunAdr (const AnsiString& funname, AnsiString& bplname, int* hlib ) { int funadr = 0; *hlib = 0; if (funname.IsEmpty()) return funadr; int i; AnsiString str; bplname = bplname.Trim().UpperCase(); if (!bplname.IsEmpty()) if (bplname.Pos(".") <= 0) bplname += ".BPL"; AnsiString nativefunname = funname.SubString(2,10000); i = nativefunname.Pos("$"); if (i > 1) nativefunname = nativefunname.SubString(1,i-1); // Поиск в загруженных TLibModule *lbm; char buf [255]; bool bplinmemory = false; funadr = 0; for (lbm = LibModuleList; lbm; lbm = lbm->next) { funadr = (int)GetProcAddress((HMODULE)lbm->instance, funname.c_str()); if (funadr) break; if (!bplname.IsEmpty()) { GetModuleFileName((HMODULE)lbm->instance, buf, 254); str = AnsiString(buf).Trim().UpperCase(); if (str.IsEmpty()) continue; str = ExtractFileName(str); if (str == bplname) bplinmemory = true; } } if (funadr) return funadr; if (bplname.IsEmpty() || bplinmemory) { str = AnsiString("Function ") + nativefunname + " not found in active modules list"; throw Exception(str); } // Подгрузить библиотеку try { *hlib = (int)LoadPackage(bplname); } catch (Exception &xcp) { *hlib = 0; throw Exception(AnsiString("LoadPackage (") + bplname + ")\r\n" + xcp.Message); } if (*hlib <= 32) { str = AnsiString("Can't load package ") + bplname; *hlib = 0; throw Exception(str); } funadr = (int)GetProcAddress((HMODULE)(*hlib), funname.c_str()); if (!funadr) { try { UnloadPackage((HINST)(*hlib)); } catch (...) {} *hlib = 0; str = AnsiString("Function ") + nativefunname + " not found in module " + bplname; throw Exception(str); } return funadr; } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // void _fastcall ??? (void) PACKAGE void __fastcall LEUP_void (const AnsiString& pfunname, const AnsiString& pbplname) { if (pfunname.IsEmpty()) return; AnsiString funname = pfunname.Trim(); AnsiString bplname = pbplname.Trim().UpperCase(); int funadr; int hlib; bool aspkg; AnsiString errmsg = ""; if (funname.SubString(1,1) == "_") aspkg = false; // dll style name else // bpl style name { funname = AnsiString("@") + funname + "$qqrv"; aspkg = true; } funadr = loc_LEUP_GetFunAdr(funname, bplname, &hlib); try { if (funadr) { if (aspkg) ((void __fastcall (*)(void))funadr)(); else ((void __stdcall (*)(void))funadr)(); } } catch (Exception &xcp) { errmsg = xcp.Message; } if (hlib) { try { UnloadPackage((HINST)hlib); } catch (...) {} } if (!errmsg.IsEmpty()) throw Exception(errmsg); return; }