gpt4 book ai didi

c++ - 如何在另一个 DLL 的 DLL 上使用 `/DELAYLOAD`

转载 作者:行者123 更新时间:2023-11-28 04:20:43 25 4
gpt4 key购买 nike

我有一个包含两个 DLL 的解决方案。第一个是“主”DLL。它恰好是一个 ODBC 驱动程序,但我认为这对这个问题并不重要。第二个 DLL 包含第一个 DLL 的所有 UI 逻辑。由于并不总是需要 UI,因此我想使用 /DELAYLOAD明确说明的功能:

The delayed loading of a DLL can be specified during the build of either a .EXE or .DLL project.

主 DLL 的项目正确引用了 UI 项目。如果我不使用 /DELAYLOAD,一切正常。这两个 DLL 将安装到同一目录中,因此我认为从另一个 DLL 中加载一个 DLL 应该很容易。但显然,事实并非如此。

一旦调用 UI DLL 中的第一个函数,应用程序(在我的例子中是任何 ODBC 客户端)就会崩溃。GetLastError() 产生 126,这显然意味着在任何搜索路径中都找不到目标 DLL。

事实上,根据 this answer 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 调用。所以我不会再看到 /DELAYLOAD 比使用 LoadLibrary()GetProcAddress() 的“老派”方式有多大优势>.

问题

有没有一种简单的方法可以让/DELAYLOAD从同一目录下的另一个DLL中找到目标DLL?

最佳答案

有。我的建议是创建一个延迟加载失败 Hook 函数。

https://learn.microsoft.com/en-us/cpp/build/reference/failure-hooks?view=vs-2019

基本上,您在主 DLL 中编写一个函数,在延迟加载失败时收到通知。在该函数中,当给定的代码指示失败时,您尝试手动调用 LoadLibrary,其路径由主 DLL 所在的文件夹加上加载失败的 DLL 的名称组成

如何从主 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;

关于c++ - 如何在另一个 DLL 的 DLL 上使用 `/DELAYLOAD`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55497001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com