如何仅部署.EXE和自定义.BPL文件?

时间:2016-05-05 07:02:58

标签: plugins bpl c++builder-2009

我想用插件开发GUI应用程序。插件包含VCL表单,这些表单继承自Plugin-Core库中的Base Forms。主应用程序可以选择动态加载哪个插件,然后选择要显示的Form子类。

在用户方面,我想为不同的模型部署主 .EXE ,Plugin-Core库和许多插件库。我可以向用户发布新的或修改现有的插件库,以便在不修改主 .EXE 和插件核心库的情况下为新设备显示新的表单。

我开发的第一个版本使用DLL方法,即Plugin-Core库和插件都是DLL形式。在用户方面一切都很好。但是,在开发人员方面,如果没有Plugin-Core DLL项目中定义的Base Forms,则无法链接插件DLL项目。这意味着Base Forms实际上是静态链接在每个插件DLL项目中,如果有一天我修改了Base Forms并重建了Plugin-Core DLL项目,我必须重建所有插件DLL项目并重新发布插件 < em> .DLL 也是用户。

在StackOverflow中搜索并询问之后,我意识到VCL Forms不能跨DLL边界继承的限制是由于RTTI冲突(?)。建议的解决方案是将库从DLL修改为BPL格式,这是我开发的第二个版本。一切都很好,除了以下两个:

  1. 插件BPL中的动态加载表单与Windows任务栏中的主 .EXE 分开。这不是我想要的。解决方案是我在 .EXE 项目中启用了“使用运行时包构建”。

  2. .EXE 项目中启用“使用运行时包构建”后,我必须向用户发布其他.BPL,例如 vcl.bpl rtl.bpl 。这不是我想要的完美。

  3. 我想知道上述两个问题可以同时解决吗?在我的想法中,如果我:

    ,我可以解决这两个问题
    1. .EXE 项目中禁用“使用运行时包构建”。
    2. 在所有 .BPL 项目中启用“使用运行时包构建”。
    3. 通过这种方式, .EXE 可以在没有 vcl.bpl rtl.bpl ,并且插件 .BPL 可以成功加载,因为依赖单元已经是主 .EXE ?我对么?但是,在所有 .BPL 项目选项中禁用了“使用运行时包构建”复选框。因此,我没有机会检查解决方案是否有效。对于冗长的描述我很抱歉,由于公司的互联网安全政策,我无法附上图片。

1 个答案:

答案 0 :(得分:1)

  

插件BPL中的动态加载表单与Windows任务栏中的主.EXE分开。这不是我想要的。解决方案是我在.EXE项目中启用了“使用运行时包构建”。

加载BPL后,将EXE的Application.Handle传递给BPL,并在创建任何Form实例之前将其分配给BPL自己的Application.Handle

或者,在Windows 7+上,您可以让EXE调用SetCurrentProcessExplicitAppUserModelID()为其任务栏按钮建立应用ID。然后,BPL中的每个表单都可以使用SHGetPropertyStoreForWindow()IPropertyStore.SetValue(PKEY_AppUserModel_ID)为其窗口设置相同的App ID。具有相同App ID的多个窗口在一个任务栏按钮下组合在一起。

有关详细信息,请参阅MSDN:Application User Model IDs (AppUserModelIDs)

  

我想知道上述两个问题可以同时解决吗?在我的想法中,如果我:

,我可以解决这两个问题      
      
  1. 在.EXE项目中禁用“使用运行时包构建”。

  2.   
  3. 在所有.BPL项目中启用“使用运行时包构建”。

  4.         

    通过这种方式,.EXE可以在没有捆绑vcl.bpl和rtl.bpl的情况下运行,并且插件.BPL可以成功加载,因为依赖单元已经是主.EXE的一部分了?我是对的吗?

没有。 BPL不能像这样使用EXE的内置单元。

如果禁用“使用运行时软件包构建”,则RTL / VCL单元将静态链接到可执行文件中。这样做的问题是给定单元的多个副本不能同时加载到内存中,因此如果相同的RTL / VCL单元静态链接,您将无法将多个BPL加载到一起(甚至根本不加载)多个BPL,甚至是EXE本身。

如果启用“使用运行时软件包构建”,则可执行文件将依赖于RTL / VCL BPL,然后必须部署这些文件。

因此,如果您的EXE和BPL共享公共单位,那么必须的单位必须通过共享BPL加载,因此内存中只存在一个单位副本。编写自定义BPL时无法避免。这意味着在 minimum ,如果您使用的是基本的RTL功能,则通常需要部署RTL.BPL,而使用VCL.BPL则需要部署。