c++ - 运行时检查失败 #0 从 kernel32.dll 加载 QueryFullProcessImageName

标签 c++ winapi windows-vista function-pointers

我有一个应用程序需要同时在 WinXP 和 Vista64 上运行。我的程序需要 QueryFullProcessImageName() 才能在 Vista 上运行,但不能在 XP 上运行。

我尝试通过 kernel32.dll 加载 QueryFullProcessImageName()(而不是静态链接),以便相同的可执行文件可以在 WinXP 和 Vista 上运行。加载它的代码是:

//only gets called on vista
bool LoadQueryFullProcessImageName()
{
  HMODULE hDLL = LoadLibrary("kernel32.dll");
  if (!hDLL) return(0);

  //Now use pointer to get access to functions defined in DLL
  fpQueryFullProcessImageName = (LPQueryFullProcessImageName)GetProcAddress(hDLL, "QueryFullProcessImageNameA"); //ANSI version
  if (!fpQueryFullProcessImageName) 
     return false;

  return true;
}

类型定义是

typedef WINBASEAPI
BOOL (*LPQueryFullProcessImageName)(
    __in HANDLE hProcess,
    __in DWORD dwFlags,
    __out_ecount_part(*lpdwSize, *lpdwSize) LPSTR lpExeName,
    __inout PDWORD lpdwSize
    );

不幸的是,当取消引用函数指针时,我在 Vista 上遇到运行时错误:

运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是用一个调用约定声明的函数调用一个以不同调用约定声明的函数指针的结果。

typedef 直接来自 .h 文件,所以我不明白为什么它会搞砸。有什么帮助吗?我尝试了很多变体,但没有运气。

最佳答案

您应该将 typedef 更改为

typedef BOOL (WINAPI *LPQueryFullProcessImageName)(
     HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize );

WINBASEAPI 用于声明静态依赖项,它不指定 __stdcall 调用约定。您使用 GetProcAddress(),因此您对静态依赖不感兴趣,但您仍然需要 __stdcall 来进行正确的调用。

关于c++ - 运行时检查失败 #0 从 kernel32.dll 加载 QueryFullProcessImageName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/696306/

相关文章:

c - 根据磁盘 ID 删除文件

windows - RegSvr32 退出代码文档?

windows - 检测键盘 Hook

asp.net - IIS7 和 Vista 上的 ASP .NET 2 的 URL 重写问题

c++ - 在我的类(class)中,我应该用什么来改变 cout/cin 的东西?

c++ - "vector iterator not incrementable"set_intersection 运行时错误

delphi - 使用 CreateProcess 进行调试

windows-7 - tortoisesvn 上下文菜单和 Windows 7/Vista UAC

c++ - SFML 白色矩形

c++ - Vulkan 计算着色器只读取部分统一缓冲区