运行时检查失败 #0 加载 kernel32.dll 中的 QueryFullProcessImageName

8

我有一个应用程序需要在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;
}

the typedef is

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文件中获取的,所以我不明白它为什么会出错。有什么帮助吗?我已经尝试了很多变体,但没有成功。

1个回答

24

你应该将typedef更改为

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接