【发布时间】:2019-02-06 20:24:45
【问题描述】:
我已将 libhunspell.dll (HunSpell) 动态链接到我的应用程序。它有效,但有一个愚蠢的问题,我不知道为什么会发生。
甚至在我使用LoadLibrary("path\\to\\libhunspell.dll"); 加载并使用它之前,在应用程序启动时它会尝试自行加载库。如果我将 libhunspell.dll 放到我的主可执行文件所在的路径中,它可以加载它,否则它会在启动应用程序后立即报告错误 - 此应用程序无法启动,因为LIBHUNSPELL.DLL 未找到。重新安装应用程序可能会解决此问题。并且应用程序无法启动。
如果LoadLibrary 会使用无效路径,我会理解,但这种情况会在可执行文件运行后立即发生,甚至在WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) 中的第一条语句执行之前(我试图放置一个断点,但它甚至没有到达它,所以这发生在之前)。
因此,我必须将 libhunspell.dll 放在与我的应用程序可执行文件相同的文件夹中,而不是放在我想要的路径中。
这可能很容易解决,尽管我不知道要寻找什么。
所以问题是 - 我如何避免它立即加载它并让它等到我使用 LoadLibrary 调用?
如果有帮助的话,我是这样链接的:
1) 在 Visual Studio 2015 中编译 libhunspell.dll(我使用 /MT 选项静态链接它,因此它没有 VC++ Redistributable 作为依赖项)。
2) 使用 implib.exe -a -c -f libhunspell.lib libhunspell.dll 创建导入库 (libhunspell.lib)
3) 使用#pragma comment(lib, "libhunspell.lib") 将其链接到正在使用它的源 .cpp 单元(它是 RAD Studio 2010,因此需要 .lib 与较新的版本不同)。
4) 稍后在同一个 .cpp 中使用 LoadLibrary 加载此库并使用它。
【问题讨论】:
-
您将不得不通过 not 使用步骤 2 和 3 来执行此操作。这将产生链接器错误,告诉您需要修复哪些代码。无疑很痛苦,所以选择简单的解决方案。
-
显然您也在“静态”加载 DLL。这就是@HansPassant 已经说过的:您链接到导入库。如果您想动态加载 DLL,请不要这样做。
-
FWIW,对于 DLL 的“静态”加载,系统必须找到该 DLL。这意味着它必须与调用应用程序位于同一目录中,或者必须位于系统路径上(与 PATH 环境变量相同)。请参阅 Microsoft 的 Dynamic-Link Library Search Order 文档。
-
我想我真正的问题是——有没有办法仍然使用 .lib (以避免使用有错误的
GetProcAddress)但在程序的后面指定 DLL 路径(而不是在编译时也不在与主可执行文件相同的目录中或路径中的某个位置)?如果我稍后在自己的路径中使用延迟加载和LoadLibrary,它确实有效。如果@RudyVelthuis 所说的是唯一选项,那么除了修改系统PATH(或与主exe相同的路径)之外,自定义DLL加载路径的选项并不多。 -
如果 GetProcAddress 有错误,那么很多人都会遇到大问题。无论如何,您可以使用导入库,但这不如动态链接(LoadLibrary + GetProcAddress)灵活。但是对于“静态”链接,您的 DLL 必须位于 MS 告诉您的位置之一。延迟加载不应与动态加载相结合。
标签: dll c++builder loadlibrary hunspell