如何为DLL静态加载相对路径?

时间:2009-12-01 19:04:46

标签: delphi dll

我有一个在Delphi 7 / Windows XP中制作的DLL,我想在Windows上的主机应用程序中静态加载(也是用Delphi制作的)。我正在使用这行代码:

procedure Prepare_HTML_Email(var MailMessage : TIdMessage;
  const FileAddress, aDetail, aAlarmType : String); stdcall; external DLL_ADDRESS;

其中DLL_ADDRESS必须是DLL所在的位置。但此时我遇到了问题。主机应用程序是一个服务,因此它在C:\WINDOWS\System32中运行,但我想将DLL放在另一个目录中,而不是C:\WINDOWS\System32中。 “external”关键字不允许使用函数跟随它,它只允许一个常量表达式。那么,我怎样才能获得DLL的路径?

5 个答案:

答案 0 :(得分:11)

首先,你不是“静态加载”任何东西。 DLL 中的 D 代表动态;无论如何,所有DLL都是动态链接的。静态链接是DCU和OBJ文件包含在程序中的方式。您无法静态链接到DLL。

您正在谈论加载时动态链接,其中由于程序的导入表中列出的函数,操作系统隐式加载DLL,而不是运行时动态链接,您可以使用任何内容调用LoadLibrary。当您使用external指令定义函数时,您在导入表中创建一个条目,据我所知,相对路径没有意义。操作系统使用certain documented search order在加载时(和运行时)查找DLL。通常,它是应用程序自己的目录,当前目录,系统目录,Windows目录,然后是PATH环境变量上的其他所有内容。

在您的情况下,当前目录和系统目录是相同的位置,并且您无论如何都无法控制它们。不要将您的DLL放在Windows目录中;已经有足够的东西不属于那里。

最好的办法是将您的DLL放在与放置服务EXE相同的目录中。如果你不想那么,那么你就可以把你的程序引导到该目录中的一个DLL中,然后使用LoadLibrary使用你想要的任何私有DLL目录加载其他所有内容。

您可以将DLL放在其他位置,然后将该目录添加到PATH环境变量中。但是,该变量是共享资源,因此在更改之前请三思而后行。

答案 1 :(得分:2)

  1. 看一下自Delphi 2010以来可用的delayed dynamic link libraries .AFAIK你无法从一个非常具体的路径加载dll,但是你可以在主机程序的第一行修改环境路径变量在使用它的导出函数之前,包括dll所在的路径。
  2. 更改代码以显式加载dll并不困难,您可以指定LoadLibrary API调用的完整路径。您将在same article中找到隐式和显式dll加载的示例。

答案 2 :(得分:1)

如果在系统路径中放置DLL的路径,那么放置它的位置无关紧要。请注意,如果您对服务进行更改,则必须重新启动才能生效。

要编辑路径变量,请转到系统属性的高级选项卡(右键单击“我的电脑”中的属性),然后按“环境变量...”按钮。更改系统变量“Path”以包含要存储DLL的目录。

解析DLL时,系统首先检查进程启动的当前目录,然后是从左到右的路径变量,并使用在它运行的第一个目录中找到的DLL ...这就是为什么将它放在C:\ Windows \ System32中时它可以工作。

答案 3 :(得分:0)

了解Windows如何在此处加载DLL:

http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx

SetDllDirectory()可能会对您有所帮助,但在XP SP1之前它不可用。

答案 4 :(得分:0)

另外值得一读(从主MSDN文档页面链接)是:

Dynamic-Link Library Redirection

它允许覆盖LoadLibrary中的硬编码DLL路径。如果它适用于服务,这可以解决问题。