c++ - 带有函数指针 : Function does not Exist 的 TypeDef

标签 c++ function typedef stdcall

问题是在不存在所请求函数的旧机器上运行代码。要检查它,请使用 LoadLibraryGetProcAddress 作为演示 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/

相关文章:

C++ : iterating the vector

c - 在 C 中保存随机生成的数字

jquery - echo paginate_links() 数字链接 wp

function - 该函数未定义。 (递归)

c++ - 当我使用 typedef 或 using for int 时,它仍然是一个 int 有多少?

c++ - 如何找到等于总和的子序列的最大子集的大小

c++ - 如何在 while 循环中保存 int 值?

c++ - 除了 self 引用之外,在 typedef 中使用标签还有其他原因吗?

c++ - typedef 结构中的下划线是什么意思?

c++ - 符号绑定(bind)如何在 linux 中为共享库工作