1

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

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

问题是我的程序现在被另一个应用程序(主机)作为库(它是一个插件)加载。这意味着 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';
4

2 回答 2

5

The program loader looks for DLLs on the system path. Just make sure that your freetype6.dll (and the DLLs that it requires) is either in the same directory as the host exe, or is in a directory that is in the file path (PATH environment variable).

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

于 2013-03-06T06:56:28.960 回答
3

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

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

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

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

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

于 2013-03-06T07:34:52.810 回答