За отстраняване на грешки в нашето бавно стартиращо приложение Delphi XE3 бихме искали да регистрираме фазата на инициализация на всички използвани единици в нашата система.
За да изпълним тази задача, имаме нужда от името на модула за всяко инициализиращо повикване.
Анализирайки данните, когато минаваме през InitNames, намираме първото име на единица вътре:
InitContext.InitTable^.TypeInfo.UnitNames
но не знаем как да извлечем подходящото име от ИД на единица I преди да извикаме процедурата за Инициализация. В документацията на кода се казва, че TypeInfo.UnitNames съдържа свързаните имена на единици на всички единици. Но как да пътувам между тях? Това не е масив, нито дълъг низ с разделители.
Кодът, където бих искал да вмъкна рутината за регистриране.
procedure InitUnits;
var
Count, I: Integer;
Table: PUnitEntryTable;
P: Pointer;
begin
if InitContext.InitTable = nil then
exit;
Count := InitContext.InitTable^.UnitCount;
I := 0;
Table := InitContext.InitTable^.UnitInfo;
{$IFDEF LINUX}
Inc(PByte(Table), InitContext.Module^.GOT);
{$ENDIF}
try
while I < Count do
begin
/////////////////////////////////////
MyLogCode( 'Unit: ' + Get UnitName here )
/////////////////////////////////////
P := Table^[I].Init;
Inc(I);
InitContext.InitCount := I;
if Assigned(P) and Assigned(Pointer(P^)) then
begin
{$IF defined(MSWINDOWS)}
TProc(P)();
{$ELSEIF (defined(POSIX) and defined(CPUX86))}
CallProc(P, InitContext.Module^.GOT);
{$ELSE}
TProc(P)();
{$ENDIF}
end;
end;
except
FinalizeUnits;
raise;
end;
end;
Прекомпилирането на System.pas ще бъде извършено чрез предложеното от Arnaud Bouchez решение.