加载的 BPL 插件列表假装为空,尽管包实际上已加载



>我在Delphi XE2中有项目组,其功能是从包加载插件。我创建了这些项目:

  • PluginInterface.bpl – 带有插件和 MainForm 接口的包
    • UClassManager.pas – 插件管理器
    • UPlugin.pas – 插件界面
  • MultiPlug2.exe – 带有可配置菜单的主窗体
    • MainUnit.pas (*.dfm) – 主窗体(MDI 所有者)
    • 等 – 某些形式(例如 Splash、数据库登录)
  • TestPlugin.bpl – 测试插件
    • UTestPlugin.pas – 测试插件接口
    • TestForm.pas (*.dfm) – 测试表(MDI 儿童)。

以下是一些列表。

我有问题

procedure TMainForm.RefreshPluginsList;
var
  Pair: TPair<string, TMenuItem>;
  I: integer;
begin
  for I := 0 to ClassManager.Count - 1 do
    RegisterPlugin(ClassManager[i]);
  for Pair in MenuDict do
    Pair.Value.Visible := Pair.Value.Count > 0;
end;

其中 ClassManager.Count 始终为零,因此从不调用RegisterPlugin。我应该怎么做才能使其成为 1 并正确注册我的插件?

编辑:我按照建议删除了Handles.Add(LoadPackage('PluginInterface.bpl'))。这无济于事。我在跟踪程序时看到 2 个管理器实例。

看起来您在不使用 BPL 的情况下制作了 EXE——要么"使用运行时包"已关闭,要么通用共享插件接口包不在"必需"列表中。

另一个可能(但不太可能)的原因是使用弱包装 - 这也意味着UClassManager单元(包括额外的实例 类管理器函数和变量)将被复制到每个二进制文件中。 http://docwiki.embarcadero.com/RADStudio/XE5/en/Using_the_Weak_Packaging_Directive

你不能也不应该动态加载该包 - 因为指向UClassManager的链接应该已经在编译时建立。因此,LoadPackage('PluginInterface.bpl')充其量是多余的,最坏的情况是破坏,应该删除。

我认为你没有这样做,所以现在你有两个类管理器实例 - 一个在 EXE 中,另一个在 DLL 中。您可以检查它是否发出命令,例如

ShowMessage(IntToHex(Integer(Pointer(ClassManager()))))

在 EXE 和两个 BPL 中,看看这些实例到底是什么。

阅读有关使用运行时包的手册或一些 Delphi 教科书。几个例子:

  • http://www.obsof.com/delphi_tips/DL613.html
  • http://pluginmgr.dennislandi.com/
  • 在 Delphi XE2 上使用运行时包进行构建
  • 如何将德尔福项目正确地划分为 BPL?
  • 如何从可执行文件调用 bpl 中的 Delphi 函数?
  • 如何在Windows/Delphi中编程插件?
  • http://delphi.about.com/od/objectpascalide/l/aa012301a.htm
  • https://groups.google.com/forum/#!topic/borland.public.delphi.vcl.components.writing/E_HyoAiai28

正确构建项目后,您可以检查您的 EXE 是否实际使用了 BPL 中的单元UClassManager,而不是制作自己的独立克隆。

您可以查看 EXE 的导入函数表和 DLL 依赖树,以查看 EXE 是否真的从正确的 BPL 调用UClassManager初始化函数。一些程序允许这样做:

  • http://wincmd.ru/plugring/fileinfo.html(和 http://www.totalcmd.net/plugring/fileinfo.html)
  • http://ntcore.com/exsuite.php
  • http://ru.wikipedia.org/wiki/Dependency_Walker

另一个选项是使用Delphi IDE菜单中的"项目/分析"命令,并选中"显示包"选项以查看哪个二进制文件包含哪个单元。您可以在安装项目分析器包后找到此命令,该包是Jedi CodeLib的一部分,http://jcl.sf.net


附言。由于您使用的是 XE2,因此我建议您避免将TList与二进制指针和危险的未经检查的类型转换一起使用。你最好把你的TClassManager建立在古老的TClassList(在Delphi 5甚至更早)或TList<TPlugin>的基础上

.PPS。由于您使用的是 XE2 并动态加载/卸载 BPL,因此请在包中避免使用array [...] of string类型的常量(或预初始化的变量)。他们正在被摧毁。我有一些想法为什么会发生这种情况以及如何在 XE3/4 中修复它,但我有点懒得实现补丁。为此,我只是切换到array [....] of PChar常量。

相关内容

  • 没有找到相关文章

最新更新