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

时间:2013-03-06 06:44:35

标签: 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';

2 个答案:

答案 0 :(得分:5)

程序加载程序在系统路径上查找DLL。只需确保您的freetype6.dll(及其所需的DLL)与主机exe位于同一目录中,或者位于文件路径(PATH环境变量)中的目录中。

供参考:http://msdn.microsoft.com/en-us/library/7d83bc18(v=vs.71).aspx

答案 1 :(得分:3)

我建议修改PATH是一种非常有创的解决方案。我建议尝试避免这种情况。您可以使用SetDllDirectory执行此操作。这将在搜索路径中添加一个目录,但会在本地对您的流程进行更改。

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

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

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

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