我有一个需要在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是
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文件,所以我无法理解为什么它会搞乱。有帮助吗?我尝试了很多变种,但没有运气。
答案 0 :(得分:21)
您应该将typedef更改为
typedef BOOL (WINAPI *LPQueryFullProcessImageName)(
HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize );
WINBASEAPI用于声明静态依赖项,它不指定__stdcall调用约定。您使用GetProcAddress(),因此静态依赖关系对您不感兴趣,但您仍需要__stdcall才能进行正确的调用调用。