我有一个我不明白的问题。我在我的应用程序中使用DLL。这个DLL需要其他DLL,我拥有所有这些DLL。如果我将库放在我的应用程序文件夹中,一切正常。
但是,在应用程序文件夹中有一堆DLL看起来很难看,所以我想将它们移动到application \ lib子文件夹。
现在改变之后,当我尝试使用它的一些功能时,我得到了外部异常。
我只更改了一行代码:
原始代码
DLLHandle := LoadLibrary(Pchar(ExtractFilePath(ParamStr(0)) + 'External.dll'))
更改后的代码
DLLHandle := LoadLibrary(Pchar(ExtractFilePath(ParamStr(0)) + 'lib\External.dll'))
在这两种情况下,DLLHandle
在加载库后都有句柄。调用GetProcAddress( DLLHandle, '_SomeFunction@8')
没有例外,GetLastError
的返回值始终为0.
你知道可能出现什么问题吗?
感谢。
答案 0 :(得分:3)
如果将DLL保存在与可执行文件相同的文件夹中,则生活会容易得多。加载库时,这是first folder searched。要将所有DLL移动到可执行目录的子文件夹中,需要所有DLL的协作。
您很可能拥有不合作的辅助DLL依赖项。因此,exe加载A很好,但是A无法加载B.您可以在配置文件模式下运行Dependency Walker进一步调试。很可能是辅助DLL正在加载隐式链接,并且这会引发异常。无论原因是什么,Depenency Walker都会引导您解决问题。
虽然您可以修改PATH变量,但这通常是不可取的。如果确实选择沿着这条路线行进,那么不要在系统范围内进行修改,只需在第一个LoadLibrary之前在运行时修改可执行进程环境。只要使用GetProcAddress显式地进行所有DLL链接,这是可行的。
所有被接受的智慧都建议您将DLL放在与可执行文件相同的文件夹中。我会回应这个建议。如果您这样做,那么您将能够使用隐式链接,这将大大简化您的代码。
另一种选择可能是放弃DLL并将所有内容直接链接到您的可执行文件中。除非你有一个插件类型的架构,否则一个大的exe是迄今为止最简单的方法。
答案 1 :(得分:1)
需要加载的其他DLL必须位于Windows的系统路径上才能找到它们。您明确定义路径时,您的应用程序可以找到External.dll。尝试将lib文件夹添加到系统路径中。