C++ 调用进程退出后是否可以将DLL保留在内存中?
我有一个DLL,加载需要5到10秒,这意味着每次编译和运行使用它的可执行文件时,我都必须等待那么长的时间。是否有一种方法可以将DLL加载到内存中,以便每次编译相应的可执行文件时都可以立即访问它?我正在QT-MinGW上编译程序,如果相关的话C++ 调用进程退出后是否可以将DLL保留在内存中?,c++,qt,dll,C++,Qt,Dll,我有一个DLL,加载需要5到10秒,这意味着每次编译和运行使用它的可执行文件时,我都必须等待那么长的时间。是否有一种方法可以将DLL加载到内存中,以便每次编译相应的可执行文件时都可以立即访问它?我正在QT-MinGW上编译程序,如果相关的话 编辑:到目前为止运气不好。在另一个程序上加载DLL似乎没有效果(原始程序仍然加载DLL,并且加载所需的时间与加载相同)。如果DLL和它的函数被加载到另一个程序中,我想我需要以不同的方式加载它们,但我不知道怎么做。现在我正在使用LoadLibrary和GetP
编辑:到目前为止运气不好。在另一个程序上加载DLL似乎没有效果(原始程序仍然加载DLL,并且加载所需的时间与加载相同)。如果DLL和它的函数被加载到另一个程序中,我想我需要以不同的方式加载它们,但我不知道怎么做。现在我正在使用LoadLibrary和GetProcAddress。创建一个显式安装的系统服务,使DLL保持加载状态。这样,初始化将在启动时发生,而不会再次发生。我建议不要采用其他大多数答案中概述的方法。虽然它们看起来很有效,但在我看来,它们就像是您的软件中的不良行为。从用户和维护人员的角度来看,我更喜欢显式安装的系统服务,而不是将某些东西挂接到winlogin.exe。您越诚实地使用Windows API和环境,跨版本和在版本升级时进行的破坏性更改就越少 如果我没有记错的话,Windows会在内存中保留一个DLL实例,因此保持该实例的活动状态应该是可行的:
#include <conio.h>
#include <windows.h>
int main()
{
HMODULE handle=LoadLibrary("yourdll.dll");
// Make shure Windows resolves the DLL
FARPROC dummy=GetProcAddress(handle,"functionInDll");
// The process will now just wait for keyboard input.
getch();
CloseHandle(handle);
return 0;
}
#包括
#包括
int main()
{
hmodulehandle=LoadLibrary(“yourdll.dll”);
//使舒尔Windows解析DLL
FARPROC dummy=GetProcAddress(句柄,“functionInDll”);
//该过程现在将只等待键盘输入。
getch();
关闭手柄(手柄);
返回0;
}
最简单的解决方案是(假设MSVC++)加载DLL延迟。当然,折衷的办法是仍然必须进行初始化,但这将不再延迟程序的其他部分。例如,您可以在后台线程上执行此操作。我不是MinGW开发人员,但您的问题非常常见,并不真正取决于您如何创建DLL。这些问题通常通过使用三种技术来解决:
- 选择DLL的唯一基址
- 绑定DLL和exe(在应用程序安装期间)
- DLL延迟加载技术的使用
- 稍微缩短加载时间,调用
DLL\u进程\u附加
DllMain部分
--image base
或--启用自动镜像base
链接器选项),则所有DLL都将具有相同的基地址(链接器的默认值)。因此,第一个DLL可以在该地址加载。加载与相同(或某些重叠地址)链接的第二个DLL时,将重新定位DLL。在重新定位过程中,DLL的代码将被修改,因此1)DLL的加载将缓慢进行2)代码的修改副本将在过程中进行(包括DLL使用的内存)3)修改副本不会在DLL的多个实例之间共享(即使所有实例都将以相同的方式修改)
我建议您首先使用示例来验证哪些DLL将在应用程序中重新定位。您应该在“视图”/“下疼痛视图”菜单中选择选项“DLL”,并在“选项”菜单的“配置突出显示”中选择“重新定位DLL”复选框。您还可以自定义显示每个DLL的哪些信息。下面的信息越多,加载程序的速度就越慢,应用程序实例之间或使用同一DLL的不同应用程序之间不共享的地址空间就越多:
在上面的示例中,您可以看到树Lenovo dllTPOSDSVC.dll
、HKVOLKEY.dll
和TPLHMM.dll
与相同的基址0x10000000
链接,并且只有一个dll(TPOSDSVC.dll
此处)将加载到该地址。另外两个DLL必须重新定位
我不能在这里写一本关于这个主题的书。我建议你检查一下关于搬迁问题的申请。您可以使用链接器选项(--image base
或--enable auto image base
似乎就是您所需要的)。您可以使用该工具(也可以在免费版中从VisualStudio获得)检查PE图像
在所有DLL都具有唯一的基址之后,您可以使用另一个工具