System.IsLibrary 与 SysInit.ModuleIsLib 有何不同?

问题描述 投票:0回答:2

System.IsLibrary

指示模块是否是共享库。

如果模块是动态链接库 (DLL),则 IsLibrary 变量为 True。

SysInit.ModuleIsLib

如果该模块是 DLL(动态链接库或包),则为 True。

两者有什么区别?

C++ Builder 有什么变化吗?

delphi c++builder
2个回答
0
投票

我认为,不应该使用

System.IsLibrary

如果我们的应用程序使用DLL,并且其所有模块(EXE和DLL)都是用Delphi编写并使用运行时包编译的,那么

System
单元的所有变量都驻留在同一位置:在
rtl???.bpl
中。该 bpl 以单个副本的形式加载到进程中,因此 EXE 和所有 DLL 都有一个
System.IsLibrary
副本。

另一方面,

SysInit
单元与每个模块单独链接。因此每个模块都有自己独立的
SysInit.ModuleIsLib
变量副本。

当然,如果某个模块是在没有运行时包的情况下编译的,它将有自己独立的

System.IsLibrary
副本,并且该变量可能具有正确的值。但我不会指望这一点。


0
投票

System.IsLibrary 在 RTL 初始化期间设置。如果 RTL 作为加载的 EXE 的一部分进行初始化(RTL 当然很可能已作为包链接),则

System.IsLibrary
为 false,否则为 true。 (请参阅下文了解如何覆盖它,尽管有效含义保持不变。)

因此,如果您编写了基于 RTL 的应用程序(在 Delphi 或 C++ Builder 中),您将看到

System.IsLibrary
始终为 False,即使您从随后动态加载的包中调用它也是如此。

如果您编写了一个库(DLL / Dylib / SO),它是一个库而不是一个包,那么它不会与加载到的应用程序共享 RTL,并且它可以加载到不基于 RTL 的应用程序中。由于它有自己的 RTL,因此当 RTL 初始化时,它会将

System.IsLibrary
设置为 True。

如果使用

LoadPackage
动态加载包,它不会重新初始化 RTL,因此
System.IsLibrary
的值保持不变。

SysInit.ModuleIsLib

SysInit
单元的一部分,正如 @Александр Кулагин 所说,它是链接到每个可执行文件和库的特殊单元。
SysInit
中变量的值由编译器控制,因此它记录了代码是如何构建的。相关变量在调用
VCLInit
时设置,如下所示:

如果代码是作为库(包括包)的一部分构建的,则

SysInit.ModuleIsLib
为真。

如果代码是作为包的一部分构建的,则

SysInit.ModuleIsPackage
为 true(因此对于不是包的库,这将为 false。

如果代码是作为库而不是包构建的,则

System.IsLibrary
设置为 true,否则保持不变。如果代码是作为库而不是包构建的,那么预计它将使用自己的 RTL。

由于它与使用 C++Builder 构建时包含的代码相同,因此使用 C++ Builder 构建代码时没有任何变化。

© www.soinside.com 2019 - 2024. All rights reserved.