我有一个在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的路径?
答案 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)
答案 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路径。如果它适用于服务,这可以解决问题。