问题是在不存在所请求函数的旧机器上运行代码。要检查它,请使用 LoadLibrary
和 GetProcAddress
作为演示 here , 但 GetProcAddress
在使用前需要 TypeDef
中函数的地址。
例如,以这两个为例,XP SP2 32 位:
typedef BOOL (__stdcall *LPFN_Wow64RevertWow64FsRedirection) (PVOID OldValue);
typedef BOOL (__stdcall *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
...
...
LPFN_Wow64RevertWow64FsRedirection wowRevert = NULL;
LPFN_Wow64DisableWow64FsRedirection wowDisable = NULL;
HINSTANCE hLib;
if(GetProcAddresses( &hLib, "kernel32.dll", 2, &wowRevert,_
"Wow64RevertWow64FsRedirection", &wowDisable, Wow64DisableWow64FsRedirection" ))
{...
代码在这里崩溃:
The procedure entry point Wow64RevertWow64FsRedirection could not be located in the dynamic link library Kernel32.dll
使用非 WINAPI typedef 实现我们自己的自定义 Wow64RevertWow64FsRedirection
很容易,但是当函数存在于 kernel32.dll 中时,如何将它们替换为基本类型?
最佳答案
我在理解您的问题时遇到了一些问题。 Wow64RevertWow64FsRedirection
函数显然不会出现在 32 位操作系统上,因此它不会出现在 32 位 Windows XP 上。因此,尝试使用 GetProcAddress
检索指向此函数的指针将失败。您收到无法找到该入口点的合理错误。如果找不到入口点,则该函数不存在,您不应尝试调用它。
您声称您可以实现自己的自定义 Wow64RevertWow64FsRedirection
函数,但我完全不明白您为什么要这样做。如果操作系统支持 WOW64 文件系统重定向,则它将提供 Wow64RevertWow64FsRedirection
函数。如果没有,则它不提供该功能,但您不需要这样的功能,因为没有 WOW64 文件系统重定向之类的东西。您无需启用、禁用或还原它。
看来您使这件事变得比需要的复杂得多。您甚至不需要首先验证进程是否为 64 位进程。您可以尝试找到 Wow64RevertWow64FsRedirection
(或 Wow64DisableWow64FsRedirection
,根据需要)的入口点,如果存在则调用它,如果不存在则忽略失败。
很简单:
BOOL RevertWOW64RedirectionIfNecessary(PVOID pOldValue)
{
typedef BOOL (WINAPI * fnWow64RevertWow64FsRedirection)(PVOID);
fnWow64RevertWow64FsRedirection pfn =
reinterpret_cast<fnWow64RevertWow64FsRedirection>(
reinterpret_cast<void*>(
GetProcAddress(GetModuleHandle(L"kernel32"),
"Wow64RevertWow64FsRedirection")));
if (pfn)
{
// The function exists, so call it through the pointer we obtained.
return pfn(pOldValue);
}
else
{
// The function does not exist, so we can't call it.
// But we don't ever need to call it in such cases,
// so do nothing and feign success.
return TRUE;
}
}
请注意,我正在调用 GetModuleHandle
函数来检索模块 kernel32.dll
的句柄(隐含了 .dll
扩展名) .我可以在此处使用 GetModuleHandle
而不是 LoadModule
,因为我知道 kernel32.dll
保证始终在任何应用程序进程中加载。由于我使用了 GetModuleHandle
,因此我也不需要释放模块句柄。
我将生成的句柄传递给 GetProcAddress
函数,同时传递一个字符串,其中包含要检索其地址的函数/过程的名称。此函数尝试检索该函数的地址,如果存在则返回;否则,它将失败并返回 NULL。
我检查它是否返回了一个有效的指针,如果是,我通过该指针动态调用该函数。否则,它返回 NULL,这意味着该函数不可用,但在那种情况下,我们甚至不需要担心它,所以代码就变成了空操作。
至于有趣的选角,参见my answer here ,这解释了这个技巧。
关于c++ - 带有函数指针 : Function does not Exist 的 TypeDef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40944793/