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;
}

类型定义是

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 文件,所以我不明白为什么它会搞砸。有什么帮助吗?我尝试了很多变种,但没有运气。

4

1 回答 1

24

您应该将 typedef 更改为

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

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

于 2009-03-30T08:09:21.060 回答