是否可以仅基于 BPLs/DCPs 未选中 "Build With Runtime Packages" 针对 BPL/DCP 构建 EXE 项目?
Can one build an EXE project against a BPL/DCP with "Build With Runtime Packages" unchecked, based solely on the BPLs/DCPs?
我有一个 BPL 项目(带有一些基础内容)和一个 EXE 项目,它的搜索路径中包含另一个项目输出(BPL 和 DCP)的位置。当使用 "Build With Runtime Packages" 构建 EXE 项目时,它构建良好。但是,它需要我部署 EXE 和 BPL。到目前为止一切顺利。
因为我宁愿只部署 EXE(无论它变大),我想我只要取消选中 "Build With Runtime Packages" 就可以了,但事实并非如此。它不会构建,并开始抱怨缺少 类。我可以编译 EXE 项目的唯一方法是将实际 BPL 项目的 DCU 的路径添加到 EXE 项目的搜索路径中。我可以这样做,但为什么我必须指向 DCU? Delphi 不能直接从 BPL 拿走它们吗?这不仅仅是品味问题,如果我走这条路,link 到 DCU,当涉及到属于表单的 DCU 时,它会向我询问表单 DFM,迫使我也包括我的来源文件夹到 EXE 项目的搜索路径,现在看起来它们正在被编译,这是令人望而却步的。每次我想编译我的 EXE 项目时,我都无法重新编译我的 BPL 项目代码库。
我希望我已经说清楚了。
感谢任何有关如何实现标题中要求的帮助。
谢谢。
link外部库有两种方式:static和dynamic。
当您使用运行时包时,这是一个 动态 linking。实际实现在 BPL
文件(实际上是一个简单的 dll)中,方法和 类 在进程启动时从中导入。这减少了 exe
大小,但需要 BPL
文件才能传送(与通常的 dll 相同)。 DCU
文件是不需要的,因为一切都已经编译和 linked,linker 只需要创建导入部分。
当禁用运行时包时,linker 必须为所有 类 和方法获取 object 文件,并将其组合到一个可执行文件中。它无法从 BPL
中提取此数据,因为它已经是 linked 可执行文件。那就得先unlink吧,分离不同的模块实现,这基本不可能。因此,您必须提供 DCU
文件,其中包含已编译的 object 代码 link 您的程序。
所以你的问题标题的答案很简单 - 不,这是不可能的。
不,你不能。如果你想使用运行时包你必须打开编译器选项来构建运行时包。
关于你问题的第二部分:
使用运行时包构建使用 *.dcp 文件进行编译(.dfm 流链接到包的资源中,因此不需要直接 *.dfm 文件)。
没有运行时包的构建需要 *.dcu 和 *.dfm 文件(以及任何其他必需的文件)。
无论哪种情况,您都需要在 library/search 路径中包含所需的文件才能 compile/build。
这是可能的,但很难实施。
为此,您需要创建第三个项目 - 加载程序。
您需要将原始 EXE 项目转换为使用运行时包构建的 DLL。
加载器可以将您的 DLL 项目 rtl.bpl、vlc.bpl 和 BPL 项目作为资源包含在加载器可执行文件中。
Loader 将需要手动完成 LoadLibrary
Windows API.
完成的所有事情
您可以阅读有关如何从内存加载 DLL 的更多信息,并找到一些代码示例以 here 开头。
我有一个 BPL 项目(带有一些基础内容)和一个 EXE 项目,它的搜索路径中包含另一个项目输出(BPL 和 DCP)的位置。当使用 "Build With Runtime Packages" 构建 EXE 项目时,它构建良好。但是,它需要我部署 EXE 和 BPL。到目前为止一切顺利。
因为我宁愿只部署 EXE(无论它变大),我想我只要取消选中 "Build With Runtime Packages" 就可以了,但事实并非如此。它不会构建,并开始抱怨缺少 类。我可以编译 EXE 项目的唯一方法是将实际 BPL 项目的 DCU 的路径添加到 EXE 项目的搜索路径中。我可以这样做,但为什么我必须指向 DCU? Delphi 不能直接从 BPL 拿走它们吗?这不仅仅是品味问题,如果我走这条路,link 到 DCU,当涉及到属于表单的 DCU 时,它会向我询问表单 DFM,迫使我也包括我的来源文件夹到 EXE 项目的搜索路径,现在看起来它们正在被编译,这是令人望而却步的。每次我想编译我的 EXE 项目时,我都无法重新编译我的 BPL 项目代码库。
我希望我已经说清楚了。
感谢任何有关如何实现标题中要求的帮助。
谢谢。
link外部库有两种方式:static和dynamic。
当您使用运行时包时,这是一个 动态 linking。实际实现在 BPL
文件(实际上是一个简单的 dll)中,方法和 类 在进程启动时从中导入。这减少了 exe
大小,但需要 BPL
文件才能传送(与通常的 dll 相同)。 DCU
文件是不需要的,因为一切都已经编译和 linked,linker 只需要创建导入部分。
当禁用运行时包时,linker 必须为所有 类 和方法获取 object 文件,并将其组合到一个可执行文件中。它无法从 BPL
中提取此数据,因为它已经是 linked 可执行文件。那就得先unlink吧,分离不同的模块实现,这基本不可能。因此,您必须提供 DCU
文件,其中包含已编译的 object 代码 link 您的程序。
所以你的问题标题的答案很简单 - 不,这是不可能的。
不,你不能。如果你想使用运行时包你必须打开编译器选项来构建运行时包。
关于你问题的第二部分: 使用运行时包构建使用 *.dcp 文件进行编译(.dfm 流链接到包的资源中,因此不需要直接 *.dfm 文件)。 没有运行时包的构建需要 *.dcu 和 *.dfm 文件(以及任何其他必需的文件)。
无论哪种情况,您都需要在 library/search 路径中包含所需的文件才能 compile/build。
这是可能的,但很难实施。
为此,您需要创建第三个项目 - 加载程序。
您需要将原始 EXE 项目转换为使用运行时包构建的 DLL。
加载器可以将您的 DLL 项目 rtl.bpl、vlc.bpl 和 BPL 项目作为资源包含在加载器可执行文件中。
Loader 将需要手动完成 LoadLibrary
Windows API.
您可以阅读有关如何从内存加载 DLL 的更多信息,并找到一些代码示例以 here 开头。