Delphi单元初始化不总是调用 [英] Delphi unit initialization not always called

查看:143
本文介绍了Delphi单元初始化不总是调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在.bpl中有一个单位,我需要一个我写的新函数的stringlist。我想让stringlist在应用程序的生命周期中持续存在,这样每次调用都可以建立在先前调用的基础上。

I have a unit within a .bpl, and I need a stringlist for a new function that I wrote. I want to the stringlist to persist for the lifetime of the app, so that each call can build on what the prior call found.

所以在全局范围内声明,我在初始化部分初始化它,如下所示:

So it's declared globally within the unit, and I initialize it in the Initialization section, like this:

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.

当我进行单元测试时,一切都很好。但是当它从主应用程序运行时,由于stringlist为零,所以我正在冒充访问冲突。所以现在我正在使用foo函数中的nil进行检查,并在必要时进行创建。但是我为什么初始化对我来说是不行的。我在初始化中放置了一个调试消息,当它作为BPL加载时,它不会运行,但如果我直接编译到dUnit exe中,则可以运行它。有任何想法吗? Delphi2005。

When I unit tested it, everything was fine. But when it gets run from the main app, I was blowing up with an access violation because the stringlist was nil. So now I'm resorting to checking for nil in the foo function and creating if necessary. But I'm at a loss as to why the initialization isn't working for me. I put a debug message right there in the Initialization, and it doesn't get run when this loads as a BPL, but DOES get run if I compile directly into my dUnit exe. Any ideas? Delphi2005.

推荐答案

Darian提醒我,我之前已经回答过:

Darian reminds me that I've answered this before:


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

If the operating system loads the BPL as part of loading the associated EXE, then not all the initialization sections will get called. Instead, only the sections from the units that are explicitly used by something else in the program get called.

如果初始化部分中的代码注册了一个类,然后你只有通过在列表中的名称查找它才间接地引用该类,则单元的初始化部分可能不会被调用。将该单元添加到程序中的任何uses子句中可以解决该问题。

If the code in the initialization section registers a class, and then you only refer to that class indirectly, say by looking for it by name in a list, then the unit's initialization section might not get called. Adding that unit to any "uses" clause in your program should solve that problem.

要解决此问题,您可以通过调用 InitializePackage 功能。它需要一个模块句柄,您可以通过调用 GetModuleHandle API函数。该函数仅调用尚未初始化的单元的初始化部分。无论如何,这是我的观察。

To work around this problem, you can initialize the package's units yourself by calling the InitializePackage function, in the SysUtils unit. It requires a module handle, which you can get by calling the GetModuleHandle API function. That function will only call the initialization sections of the units that haven't already been initialized. That's my observation, anyway.

如果您调用 InitializePackage ,那么您还应该调用 FinalizePackage 。当您的软件包卸载时,将自动初始化所​​有已经完成的单元的完成部分。

If you call InitializePackage, then you should also call FinalizePackage. When your package gets unloaded, the finalization sections will get called for all the units that were automatically initialized.

如果操作系统不自动加载你的包,然后你正在加载它与 LoadPackage 函数。它为您初始化所有包的单位,因此您不需要自己调用 InitializePackage 。同样地, UnloadPackage 将为您完成所有事情。

If the OS does not automatically load your package, then you are loading it with the LoadPackage function. It initializes all the package's units for you, so you don't need to call InitializePackage yourself. Likewise, UnloadPackage will finalize everything for you.

这篇关于Delphi单元初始化不总是调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆