启动应用程序后立即加载动态链接的DLL

时间:2018-08-31 19:26:17

标签: dll c++builder loadlibrary hunspell

我已将 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 ++可再发行组件作为依赖项)。

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加载并使用了该库。

2 个答案:

答案 0 :(得分:3)

通过链接导入存根(libhunspell.lib),操作系统将为您加载DLL,因为它现在是 static 依赖项。

一种方法是通过链接器选项将库指定为延迟负载依赖项:/DELAYLOAD:libhunspell.lib。然后,您可以在DLL上调用LoadLibrary。

唯一的选择是停止在链接器步骤中包含.lib,使其真正成为动态依赖项。

答案 1 :(得分:1)

我假设您为 DLL 做了添加到项目 *.lib文件。这是在应用程序初始化(在创建表单之前)中完成的一种“静态”链接。因此它有两个缺点。

  1. DLL 必须与Apps EXE 文件位于同一路径
  2. 有时 DLL 文件名被锁定(无法更改)

优点是您不需要为 DLL 加载做任何编码,就像VCL为您做的一样...因此您的应用程序不应包含LoadLibrary,GetProcAddress调用只需在*.h文件中加上适当的导入声明即可...

要进行动态链接,您需要从项目中删除*.lib,并按照建议的 josh poley 使用WinAPI LoadLibrary + GetProcAddress来加载 DLL 。这里是一个例子:

请注意,在某些情况下,GetProcAddress中存在/(是?)错误,导致无法从您的 DLL 中加载所有功能。尤其是如果 DLL 具有旧的旧名称处理,则功能计数很高,并且 DLL 是在与所讨论的处理不兼容的编译器上创建的。