如何在另一个 DLL 上使用 '/DELAYLOAD' 的 DLL
How to use `/DELAYLOAD` on a DLL from another DLL
>我有一个有两个DLL的解决方案。第一个是"主"DLL。它恰好是一个 ODBC 驱动程序,但我认为这对这个问题并不重要。 第二个 DLL 包含第一个 DLL 的所有 UI 逻辑。由于并不总是需要 UI,我想使用/DELAYLOAD
功能,该功能明确指出:
可以在生成 .EXE或.DLL项目。
主 DLL 的项目正确引用了 UI 项目。如果我不使用/DELAYLOAD
,每个薄都很好用。这两个 DLL 将安装到同一个目录中,所以我认为从另一个 DLL 中加载一个 DLL 应该很容易。但显然,事实并非如此。
一旦调用 UI DLL 中的第一个函数,应用程序(在我的情况下是任何 ODBC 客户端)就会崩溃。GetLastError()
产生 126,这显然意味着在任何搜索路径中都找不到目标 DLL。
事实上,根据这个答案,LoadLibrary()
确实查看了调用可执行文件的目录,但没有查看当前执行的 DLL 的目录。我假设/DELAYLOAD
也只是在引擎盖下使用LoadLibrary()
,对吗?
如果我将可执行文件复制到驱动程序的安装目录中,它就可以正常工作,这证明了我的假设,即它只是不在当前 DLL 的目录中查找。
公寓从那里,我也能够通过调用它运行
LoadLibrary(L"C:\absolute\path\to\UI.dll");
就在加载 UI DLL 的第一个函数之前。 我还能够以编程方式确定此路径
wchar_t buffer[512];
GetModuleFileName(hThisDLL, buffer, sizeof(buffer));
但是,我必须使用此逻辑覆盖每个 UI 调用。因此,与使用LoadLibrary()
和GetProcAddress()
的"老派"方式相比,我再也看不到/DELAYLOAD
的优势了。
问题
有没有一种简单的方法可以让/DELAYLOAD
从同一目录中的另一个 DLL 中找到目标 DLL?
有。 我的建议是创建一个延迟-加载-失败钩子函数。
https://learn.microsoft.com/en-us/cpp/build/reference/failure-hooks?view=vs-2019
基本上,您在主 DLL 中编写一个函数,该函数在延迟加载失败时收到通知。 在该函数中,当给定的代码指示失败时,您尝试使用由主 DLL 所在的文件夹以及加载失败的 DLL 的名称组成的路径手动调用 LoadLibrary
如何从主 DLL 中获取主 DLL 取决于您。 有很多方法。
像这样:
FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
FARPROC fpRet = NULL;
switch (dliNotify)
{
case dliStartProcessing:
break;
case dliNotePreLoadLibrary:
break;
case dliNotePreGetProcAddress:
break;
case dliFailLoadLib:
{
std::string newPath = GetMyModulePath();
newPath += "\";
newPath += pdli->szDll;
fpRet = reinterpret_cast<FARPROC>(::LoadLibrary(csDir));
}
break;
case dliFailGetProc:
break;
case dliNoteEndProcessing:
break;
default:
break;
}
return fpRet;
}
//
// Set access to our delay load hook.
//
PfnDliHook __pfnDliFailureHook2 = delayHook;
- 挂起和取消挂起一个文件DLL
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 从C++dll访问C#中的一行主要参数
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- C++:将外部库链接到dll库
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 不同的Visual Studio版本中缺少.dll
- 从DLL中删除类的实例
- 如何包装第三方DLL在R中使用
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Python ctypes:不会按预期加载 dll
- 如何在另一个 DLL 上使用 '/DELAYLOAD' 的 DLL