2009-03-30 2 views
6

У меня есть приложение, которое должно запускаться как на WinXP, так и на Vista64. Моя программа требует QueryFullProcessImageName() для работы с Vista, но не с XP.Ошибка проверки выполнения # 0 Загрузка QueryFullProcessImageName из kernel32.dll

Я пытаюсь загрузить QueryFullProcessImageName() (вместо связывания статически) через файл kernel32.dll, чтобы тот же исполняемый файл мог запускаться как на 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, когда указатель функции разыменовывается:

Run-Time Check Failure # 0 - Значение ESP не было должным образом сохранено в вызове функции. Обычно это результат вызова функции, объявленной с одним вызовом, с указателем функции, объявленным с другим соглашением о вызовах.

typedef прямо из файла .h, поэтому я не могу понять, почему это испортится. Любая помощь? Я попробовал множество вариантов, но не повезло.

ответ

20

Вы должны изменить ЬурейиЙ к

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

WINBASEAPI используются для объявления статических зависимостей и не определяет __stdcall соглашения о вызове. Вы используете GetProcAddress(), и поэтому статическая зависимость вас не интересует, но вам все равно нужен __stdcall для правильной активации вызова.