【问题标题】:Delphi unit initialization not always calledDelphi 单元初始化并不总是被调用
【发布时间】:2011-01-06 18:59:35
【问题描述】:

我在 .bpl 中有一个单元,我需要一个字符串列表用于我编写的新函数。我希望字符串列表在应用程序的整个生命周期内保持不变,以便每次调用都可以建立在先前调用找到的内容之上。

所以它在单元内全局声明,我在初始化部分对其进行初始化,如下所示:

var
  ProductLookup : TStrings;  
...

function foo : boolean;
begin
  result := (ProductLookup.IndexOfName('bar') >=0); //blow up here. It's nil. Why?
end;
....

initialization
  ProductLookup := TStringList.Create;  // This should get run, but doesn't.

finalization
  FreeAndNil(ProductLookup);

end.

当我对它进行单元测试时,一切都很好。但是当它从主应用程序运行时,我因访问冲突而崩溃,因为字符串列表为 nil。所以现在我求助于检查 foo 函数中的 nil 并在必要时创建。但是我不知道为什么初始化对我不起作用。我在初始化中放了一条调试消息,当它作为 BPL 加载时它不会运行,但是如果我直接编译到我的 dUnit exe 中就会运行。有任何想法吗? Delphi2005.

【问题讨论】:

标签: delphi initialization delphi-2005


【解决方案1】:

达里安提醒我I've answered this before

如果操作系统加载 BPL 作为加载相关 EXE 的一部分,则并非所有初始化部分都会被调用。相反,只有那些被程序中的其他东西明确使用的单元中的部分才会被调用。

如果初始化部分中的代码注册了一个类,然后您只是间接引用该类,例如通过在列表中按名称查找它,那么单元的初始化部分可能不会被调用。将该单元添加到程序中的任何“使用”子句中应该可以解决该问题。

要解决此问题,您可以通过调用 SysUtils 单元中的InitializePackage 函数自己初始化包的单元。它需要一个模块句柄,您可以通过调用GetModuleHandle API 函数来获得它。该函数只会调用尚未初始化的单元的初始化部分。无论如何,这是我的观察。

如果您拨打InitializePackage,那么您也应该拨打FinalizePackage。当你的包被卸载时,将调用所有自动初始化的单元的终结部分。

如果操作系统自动加载你的包,那么你正在使用LoadPackage 函数加载它。它会为您初始化所有包的单位,因此您无需自己致电InitializePackage。同样,UnloadPackage 将为您完成所有工作。

【讨论】:

    【解决方案2】:

    在 Quality Central 中仅找到一个参考,但可能还有更多。包括 LoadPackage 引用的解决方法。

    http://qc.embarcadero.com/wc/qcmain.aspx?d=61968

    【讨论】:

    【解决方案3】:

    在某些情况下,并非 BPL 中的每个单元都必须被初始化。如果我不得不猜测,我会说这个 BPL 在加载时链接到您的程序,而不是稍后动态加载?尝试将您正在使用的设备名称放入 DPR 中程序的 uses 列表中。那应该可以解决它。

    【讨论】:

    • 这里的复杂之处在于,大约有 100 个不同的 EXE 和 .BPL 使用这个特定的 .BPL,我不允许重新构建它们。因此,明智的方法并不总是奏效。好主意,而且 +1 通常是一种很好的技术。
    【解决方案4】:

    你是如何加载 bpl 的?您是将其留给 Delphi 进行加载还是手动加载 bpl?如果您手动加载 bpl,您是将其加载为“直接”dll 还是使用 LoadPackage 将其加载为 delphi 包?我认为要么让 vcl 加载它(通过 requires 处理),要么使用 LoadPackage 来让 vcl 运行初始化部分...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多