【问题标题】:What is the best way in Delphi to generate a list of forms/units in the order they load?Delphi中按加载顺序生成表单/单元列表的最佳方法是什么?
【发布时间】:2019-07-29 02:14:32
【问题描述】:

我遇到了一个问题,即文件在启动时不断删除,我无法找到负责的代码。我最终将 Vcl.Dialogs 添加到所有单元并创建了一个如下所示的初始化部分:

initialization
begin
  ShowMessage('Inside [Unit Name Here]');
end;

这很痛苦。有没有一种简单的方法可以按照它们触发的顺序生成表单/单元列表?

更新:2019-08-01有用的 MAP 链接

这里有两个链接可能有助于理解 DELPHI 地图文件

  1. http://docwiki.embarcadero.com/RADStudio/Rio/en/API_%28%2A.map%29

  2. Understanding Delphi MAP File

【问题讨论】:

标签: delphi initialization


【解决方案1】:

你真的不需要去修改你的源单元那么麻烦。我想你会发现使用下面的方法会发现行为不端的单元 比以某种方式生成单位列表然后耕种要快得多 通过它。

如果您查看 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 设置为 Count 值的一半。运行你的应用程序,当断点发生时,检查是否 该文件已被删除。

然后您可以通过以下值执行binary search 计数(如果文件仍然存在,则继续当前运行,或重置应用程序 并将通过计数减半)以准确确定哪个单元导致文件被删除。 因为你可以使用二分搜索来做到这一点,它会迅速收敛到 正在删除文件的单位。当然,你可以追溯到单位的 断点时的初始化代码(如果它已使用调试信息编译) 在 TProc(P)() 上按 F7 会跳闸;

【讨论】:

  • 调试101,喜欢答案;)
  • 您也可以在 DeleteFile api 处设置断点并观察调用堆栈(解决谁在删除我的文件问题)?
  • @Remko:也许,但这与 OP 的实际要求相差甚远。
【解决方案2】:

您可以检查地图文件的分段部分。带有 C=ICODE 的条目是那些按照执行顺序具有初始化部分的单元。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-03-24
  • 2011-02-26
  • 2015-07-01
  • 1970-01-01
  • 2019-01-11
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
相关资源
最近更新 更多