delphi - Delphi DLL组织-静态和动态加载

标签 delphi dynamic dll static libraries

我想这是一个常见的问题,但是四处搜寻并没有提出解决方案。我在加载库时遇到了一些麻烦。

我为该库提供的资源是利用静态加载,这很好。我正在使用的其余库是动态加载的。

问题是我的程序现在由另一个应用程序(主机)作为库(它是一个插件)加载。这意味着HOST可执行文件的目录不是我的应用程序的程序目录。

静态加载的库(只是一个用于字体渲染的简单库)位于我的程序目录中,并且当我将软件作为插件加载时,找不到该库。当我将软件作为“独立”程序(没有主机)加载时,没有问题。

通过将“缺少的”库放入主机应用程序的文件夹中,我能够解决此问题,但这是一个不好的解决方案。

通过提供指向库名称的直接路径,我也能够解决该问题,但这也是一个不好的解决方案。我不知道最终用户将在哪里安装我的软件。

有什么办法可以解决此问题,而不必重写代码以使用动态加载?

要继续使用静态加载,必须注册该库吗?我认为注册该库太具侵入性,因为其他程序可能正在使用它的不同版本。

const
  ft_lib = 'freetype6.dll';  //here is our problem. I could put a direct path
                             //here, to fix it, but I will not know this path
                             //on an end-user's machine

type
  FT_Library = Pointer;

function  FT_Init_FreeType(out alibrary : FT_Library ) : FT_Error;
  cdecl; external ft_lib name 'FT_Init_FreeType';

最佳答案

我建议修改PATH是一种侵入性很强的解决方案。我建议尝试避免这种情况。您可以使用SetDllDirectory做到这一点。这会将目录添加到搜索路径,但是将在本地对您的过程进行更改。

您的主机应用程序应在加载DLL之前立即调用SetDllDirectory。然后,将使用修改后的搜索路径来解析DLL的任何依赖项。成功加载DLL后,再次调用SetDllDirectory将搜索路径恢复为其默认值。

如果您不控制主机,则实施此方法可能会很棘手。您需要在DLL中调用SetDllDirectory,否则为时已​​晚。您可以在主机和插件之间放置另一层。该层可以修改DLL搜索路径,然后使用LoadLibrary加载使用隐式链接的DLL。

另一个明显的选择是停止使用隐式链接。使用LoadLibrary解析所有依赖项。实际上,这并不像听起来那么难。

在现代的Delphi中,您也可以使用延迟加载。只要修改了DLL搜索路径,就可以在调用延迟加载的导入之前对其进行解析。

关于delphi - Delphi DLL组织-静态和动态加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15240729/

相关文章:

c++ - 无法通过单击程序来运行程序,而我可以从终端运行程序

.net - 在多个框架中构建库dll

javascript - 如何将动态 javascript 代码注入(inject)父页面上已存在的 iframe 中

c++ - c/c++ Linux 相当于 "bool DllMain()"- 但我需要将失败返回给 dlopen()

c++ - 将整数从 VB.Net 传递到 C++ dll

delphi - 如何使自定义 GUI 控件对屏幕阅读器可见?

xml - 从 XML 数据中读取 URL

Delphi:TList 创建,内存错误

delphi - Indy "Could not load SSL Library"与 Delphi 2007/Apache

java - 如何动态加载策略(Strategy Pattern)?