运行时包加载与静态链接

时间:2015-04-12 12:58:24

标签: delphi

所以,我有一个自己写的运行时包。如果包是静态链接的,则使用的项目具有对导出数据的完全访问权限,因为编译器完全了解从中导入的内容,对不对?但它也可以通过LoadPackage()动态加载包。但是,如何使用类导入的复杂数据结构呢?除了使用FindClass(' TSomeClass')和调用RTTI来操作导入类的实例之外,我找不到一种可行的方法。

2 个答案:

答案 0 :(得分:5)

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

IDE知道包中的内容,因为它知道如何在所有单元中找到Register过程,并且该过程告诉IDE有关可用类的信息。

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

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

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

为您的所有包定义接口或公共基类'有课程。将该类的定义放在其自己的包中的单元中,我们将其称为 Shared.bpl 。包括"中的包裹要求"所有其他软件包的列表您的EXE。现在,一切都可以引用共享单元和公共基类。

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

答案 1 :(得分:0)

简短回答:

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

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

不幸的是,Delphi不允许这样做,可能是由于政治原因,您可以尝试对其进行破解,请参见下面的详细答案。

长答案:

显然,DCP向编译器/链接器/ Delphi yadayadayada描述了那些包/ DLL / BPL类型的内容。

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

那么BPL可能包含“实现”。

现在这是问题开始的地方。这些BPL是“自动加载的”,正如前面提到“导入表”所提到的那样。

您可以尝试“修改” /更改导入表,以使这些BPL不再自动加载。

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

我不确定它是否与执行“加载程序包”操作一样简单。

也许加载的过程更像是获取指向例程/方法/类的指针,不确定其工作原理。

但是也许该代码可以重复使用,所以您要做的就是“侵入”导入表并侵入“ load bpl”并禁用它。

然后,您应该能够用自己的自定义加载代码替换该代码,并且也许最终可以“重新修补”到其他导入例程中……就像调用getprocaddress的例程,如果需要的话,不确定最后一部分。 / p>

无论如何,这对于Delphi开发人员来说是很草率的,因为没有功能可以自己完成这个小的“导入表” /“加载步骤”。

尽管这是政治因素,但没有技术上的原因可以延迟该时间,由您自定义,然后在必要时致电其余人员。

由于某些原因,他们不希望您手动加载这些BPL。他们可能希望您以这种方式继续使用IDE。

如果您能够手动加载这些内容,则也许不再需要IDE。

当前,IDE必须指定从何处加载这些内容,如果没有IDE,它将变得很困难。尽管可能在某处也有一些编译器选项可以指定相同的选项,但是很少有人会使用它。

在我看来,这种产品似乎有些“怪异”,我必须坦白地说,这真是太愚蠢了。

例如,他们对winsock进行了相同的操作,它有两个不同的版本,非常容易手动加载,因此您可以选择使用哪个版本,而不必总是使用v1或v2。为了方便他们延迟这些getprocs等等,但是他们没有...

如果这样做的话,Delphi将与Windows 95/98更加向后兼容,目前,Delphi exes不再适用于那些较旧的操作系统,尽管没有真正的技术原因无法运行,但基本上必须这样做通过加载DLL,只需几行代码就可以很容易地使其工作。

这可能又是一种政治,因为使Delphi只支持Delphi创作者和Microsoft之间达成的协议的最新Windows版本。

与Windows 10相同,它可以检测到较旧的处理器,然后拒绝在其上运行,删除/破解这几行代码/指令将使Windows 10在较旧的处理器上运行。惊喜! = D