Delphi 运行时包加载与静态链接

Delphi 运行时包加载与静态链接,delphi,Delphi,因此,我有一个自己编写的运行时包。如果包是静态链接的,那么使用的项目可以完全访问导出的数据,因为编译器完全了解从中导入的内容,对吗?但也可以通过LoadPackage()动态加载包。但是,如何处理导入的复杂数据结构(如类)?除了构造复杂的表达式,比如使用FindClass('TSomeClass')并调用RTTI对导入类的实例进行操作之外,我找不到其他可行的方法。编译器完全了解包中的内容,因为DCU和DCP文件告诉它包中的内容 IDE知道包中有什么,因为它知道如何在所有单元中找到寄存器过程,并且

因此,我有一个自己编写的运行时包。如果包是静态链接的,那么使用的项目可以完全访问导出的数据,因为编译器完全了解从中导入的内容,对吗?但也可以通过LoadPackage()动态加载包。但是,如何处理导入的复杂数据结构(如类)?除了构造复杂的表达式,比如使用FindClass('TSomeClass')并调用RTTI对导入类的实例进行操作之外,我找不到其他可行的方法。

编译器完全了解包中的内容,因为DCU和DCP文件告诉它包中的内容

IDE知道包中有什么,因为它知道如何在所有单元中找到
寄存器
过程,并且该过程告诉IDE关于可用类的信息

在大多数情况下,程序知道包中有什么,因为程序使用了包中的单元,并且编译器保证在运行时提及这些单元中的事物名称将解析为BPL文件中相应的事物。这包括在程序的导入表中提到BPL文件,以便操作系统自动加载BPL

如果您希望加载的BPL列表只能在运行时确定,那么您不能使用这些包中的任何单元。您必须动态加载包

还有一个问题是如何使用这些软件包中的内容。您可以尝试使用RTTI来发现整个内容。那可不是野餐。相反,定义一个所有相关模块都将使用的中间包

为所有包的类定义一个接口或公共基类。将该类的定义放在它自己的包中的一个单元中,我们称之为Shared.bpl。将该软件包包括在所有其他软件包和EXE的“需要”列表中。现在,所有内容都可以引用共享单元和公共基类


这正是德尔福本身所做的。共享包称为RTL和VCL。这里已经定义了几个常见的基类,包括
TComponent
。在您的情况下,听起来您需要一些超出
TComponent
的通用定义。

编译器完全了解包中的内容,因为DCU和DCP文件告诉它包中的内容

IDE知道包中有什么,因为它知道如何在所有单元中找到
寄存器
过程,并且该过程告诉IDE关于可用类的信息

在大多数情况下,程序知道包中有什么,因为程序使用了包中的单元,并且编译器保证在运行时提及这些单元中的事物名称将解析为BPL文件中相应的事物。这包括在程序的导入表中提到BPL文件,以便操作系统自动加载BPL

如果您希望加载的BPL列表只能在运行时确定,那么您不能使用这些包中的任何单元。您必须动态加载包

还有一个问题是如何使用这些软件包中的内容。您可以尝试使用RTTI来发现整个内容。那可不是野餐。相反,定义一个所有相关模块都将使用的中间包

为所有包的类定义一个接口或公共基类。将该类的定义放在它自己的包中的一个单元中,我们称之为Shared.bpl。将该软件包包括在所有其他软件包和EXE的“需要”列表中。现在,所有内容都可以引用共享单元和公共基类

这正是德尔福本身所做的。共享包称为RTL和VCL。这里已经定义了几个常见的基类,包括
TComponent
。在您的情况下,听起来您需要一些超出
t组件
的通用定义。

简短回答:

您需要的是编译器/链接器来设置您,并使用DCP来完成所有类型的链接等

然后BPL的加载应该由您在自定义代码中延迟/完成

不幸的是,Delphi不允许这样做,可能是出于政治原因,您可以尝试破解它,请参阅下面的详细答案

长答覆:

DCP似乎向编译器/linker/Delphi Yadayada描述了那些包/DLL/BPLs类型中的内容

这些DCP可以被视为这些DLL/BPL的接口,这些DCP可能以某种方式编译到可执行文件中

那么BPL可能包含“实现”

现在问题就从这里开始。这些BPL是“自动加载”的,正如其他人已经提到的“导入表”

您可以尝试的是“nuking”/更改导入表,以便不再自动加载这些BPL

然后您可以尝试手动加载这些BPL

我不确定这是否和执行“加载包”操作一样简单

也许加载更像是获取指向例程/方法/类的指针,但不确定它是如何工作的

然而,该代码可能可以重复使用,因此您所需要做的就是“破解”导入表,破解“加载bpl”并禁用它

然后,您应该能够用自己的自定义加载代码替换它,也许最终会“重新修补”到其他导入例程中。。。像调用getprocaddress之类的例程(如果需要的话),不确定最后一部分

不管怎样,Delphi开发人员认为这是非常草率的,因为没有任何功能可以自己完成这个“导入表”/“加载步骤”

这是政治在起作用,没有技术上的理由不能推迟,由你自己做,然后在必要时打电话给其他人

出于某些原因,他们不希望您手动加载这些BPL。他们可能希望你继续使用这个IDE