首先,请原谅我不知道正确的术语,我确定有一个非常常见的技术名称,我可以简单地谷歌寻求帮助 - 但如果我不知道我找不到帮助这个词开头。
我正在Delphi 7中构建一个模块化系统。有一些应用程序和一堆DLL。所有应用程序共享这些DLL,以及一些DLL使用其他DLL。 DLL目前保存在与应用程序相同的位置。我想把所有这些DLL放在一个子文件夹中(EXE的其他地方)但当然Delphi不知道如何找到它们。
有没有办法可以指示我的Delphi应用程序在DLL的某个目录中查找?它不能使用Contstants,因为可以选择指定DLL的存储位置。
这些DLL只是StdCall函数的简单集合,没有什么特别的。
修改
解释为什么我要将DLL保存在他们自己的文件夹中的原因:我正在构建的这个系统将这些DLL视为附加组件。默认情况下,系统可能甚至没有任何加载项。另一方面,它还允许各个供应商构建其他DLL并将它们作为附加组件包含在内。然后,需要这些附加组件的每个应用程序将被定向到找到它们的文件夹。 它自己的应用程序将拥有自己的DLL,它将与应用程序位于同一目录中。但供应商的DLL我想保持独立。
如下面的答案所述,我最好的选择是实现DLL导入方法,因为A)我可以为它导入的每个DLL指定一个路径,B)我可以更好地控制每个DLL的使用(是吗?是否需要加载?)和C)每个DLL在技术上可以单独位于不同的文件夹中(供应商可能希望构建自己的文件夹结构)。这个系统还很成熟,但我打算用它进一步提高灵活性。
答案 0 :(得分:5)
如果您在代码中动态加载DLL,则可以随意存储它们,因为无论如何必须将完整路径传递给LoadLibrary/Ex()
。如果您是静态链接到DLL,那么您可以使用SetDllDirectory()
指定要包含在操作系统的DLL搜索路径中的其他路径。
答案 1 :(得分:4)
您可以使用PATH执行此操作,但我建议您不要这样做。这是一种残酷而不灵活的方法。当然,您需要更改系统范围的PATH,以便在可执行加载时产生任何影响。
您可以使用LoadLibrary
和GetProcAddress
明确加载DLL。如果有很多进口产品那就不好玩了,但不过它可能是一个不错的选择。请记住,如果沿着这条路线前进,每个DLL都必须切换到显式链接。
有一种名为DLL Redirection的东西,但MS不建议您使用它。他们建议您使用并排组件。话虽如此,Visual Studio团队在VS2010中使用MSVC运行时从远程组件移动远离,因为在先前版本中并排引起了痛苦。
所以,尽管有各种选择,我真的相信最好的解决方案是将所有DLL放在与可执行文件相同的目录中。如果你可以克服文件夹看起来不整洁,那么它将使生活更简单。对这个问题来说,这是一个微不足道的努力解决方案。
<强>更新强>
您的问题的更新提供了这些DLL是可选附加组件的额外信息。在这种情况下,您除了使用与LoadLibrary
和GetProcAddress
的显式链接外别无选择。
答案 2 :(得分:2)
我强烈建议您将DLL保留在与应用程序相同的文件夹中。
如果您真的想要将DLL放在一个单独的文件夹中,那么您需要知道是否可以使用LoadLibrary API加载DLL,这也允许指定路径。但是,如果DLL是静态加载的,则执行搜索的是Windows。 Windows搜索首先查找应用程序文件夹,然后搜索Windows PATH。此外,由于Delphi 7仅创建32位应用程序,因此在Windows 64位下可能会变得混乱。
答案 3 :(得分:2)
在Windows上,有一个“DLL search order”。其中一个搜索路径是The directory from which the application loaded
,这就是为什么它们与EXE位于同一文件夹中的原因。
如果您静态链接到DLL,则必须在将EXE加载到内存时加载它们。这是在执行第一行代码之前。所以,你依赖于其中一个搜索路径中的DLL。在这种情况下,您将无法设置路径,并且必须在加载程序之前进行设置。
如果要动态链接到DLL,则可以在代码中使用LoadLibrary
/ LoadLibraryEx
在运行时加载DLL。使用这些函数,您必须指定DLL的路径,因此DLL可以在任何地方。在这种情况下,我觉得将DLL放在一个单独的文件夹中是有效的,以保持整洁。只要您不将DLL放入Windows System32文件夹之类的共享位置,就可以避免很多麻烦。
答案 4 :(得分:0)
临时解决方案是:
您可以在应用程序的快捷方式中设置DLL路径(在&#34;开始于&#34;框中)。