Delphi 中按加载顺序生成 forms/units 列表的最佳方法是什么?
What is the best way in Delphi to generate a list of forms/units in the order they load?
我遇到了一个问题,文件在启动时一直在删除,我无法找到相关代码。我最终将 Vcl.Dialogs 添加到所有单元并创建了一个如下所示的初始化部分:
initialization
begin
ShowMessage('Inside [Unit Name Here]');
end;
这很痛苦。有没有一种简单的方法可以按发射顺序生成 forms/units 的列表?
更新:2019-08-01(有用的 MAP 链接)
这里有两个链接可能有助于理解 DELPHI 地图文件
http://docwiki.embarcadero.com/RADStudio/Rio/en/API_%28%2A.map%29
Understanding Delphi MAP File
您可以检查地图文件的分段部分。带有 C=ICODE 的条目是那些按执行顺序具有初始化部分的单元。
您真的不需要费心去修改您的源单位。我想你会发现使用下面的方法会找到行为不端的单元
比以某种方式生成单位列表然后耕种要快得多
你的方式。
如果您在 System.Pas 中查找,您会找到这样的过程 InitUnits(来自 D7)。
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;
[...]
try
while I < Count do
begin
P := Table^[I].Init;
Inc(I);
InitContext.InitCount := I;
if Assigned(P) then
begin
TProc(P)();
end;
end;
except
FinalizeUnits;
raise;
end;
end;
这是调用每个单元的初始化代码的代码。它通过单元工作并调用初始化部分(如果有的话)
每个单位通过电话
TProc(P)();
您可以在循环之前检查 Count 的值;如果它向上,不要感到惊讶
即使是一个相对简单的项目,也有几百。
在 TProc(P)() 上放置一个断点;行并右键单击并将 PassCount 设置为
计数值的一半。 运行 你的应用程序和当断点跳闸时,检查是否
该文件已被删除。
然后您可以 binary search 通过值
计数(通过继续当前 运行 如果文件仍然存在,或者重置应用程序
并将通过计数减半)以准确确定哪个单元导致文件被删除。
因为您可以使用二分查找来执行此操作,所以它会迅速收敛到
删除文件的单位。当然,你可以追查单位的
断点时的初始化代码(如果已使用调试信息编译)
在 TProc(P)();
上按 F7 跳闸
我遇到了一个问题,文件在启动时一直在删除,我无法找到相关代码。我最终将 Vcl.Dialogs 添加到所有单元并创建了一个如下所示的初始化部分:
initialization
begin
ShowMessage('Inside [Unit Name Here]');
end;
这很痛苦。有没有一种简单的方法可以按发射顺序生成 forms/units 的列表?
更新:2019-08-01(有用的 MAP 链接)
这里有两个链接可能有助于理解 DELPHI 地图文件
http://docwiki.embarcadero.com/RADStudio/Rio/en/API_%28%2A.map%29
Understanding Delphi MAP File
您可以检查地图文件的分段部分。带有 C=ICODE 的条目是那些按执行顺序具有初始化部分的单元。
您真的不需要费心去修改您的源单位。我想你会发现使用下面的方法会找到行为不端的单元 比以某种方式生成单位列表然后耕种要快得多 你的方式。
如果您在 System.Pas 中查找,您会找到这样的过程 InitUnits(来自 D7)。
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;
[...]
try
while I < Count do
begin
P := Table^[I].Init;
Inc(I);
InitContext.InitCount := I;
if Assigned(P) then
begin
TProc(P)();
end;
end;
except
FinalizeUnits;
raise;
end;
end;
这是调用每个单元的初始化代码的代码。它通过单元工作并调用初始化部分(如果有的话) 每个单位通过电话
TProc(P)();
您可以在循环之前检查 Count 的值;如果它向上,不要感到惊讶 即使是一个相对简单的项目,也有几百。
在 TProc(P)() 上放置一个断点;行并右键单击并将 PassCount 设置为 计数值的一半。 运行 你的应用程序和当断点跳闸时,检查是否 该文件已被删除。
然后您可以 binary search 通过值 计数(通过继续当前 运行 如果文件仍然存在,或者重置应用程序 并将通过计数减半)以准确确定哪个单元导致文件被删除。 因为您可以使用二分查找来执行此操作,所以它会迅速收敛到 删除文件的单位。当然,你可以追查单位的 断点时的初始化代码(如果已使用调试信息编译) 在 TProc(P)();
上按 F7 跳闸