Ошибка проверки во время выполнения № 0 при загрузке QueryFullProcessImageName из kernel32.dll
-
22-08-2019 - |
Вопрос
У меня есть приложение, которое необходимо запустить как на WinXP, так и на Vista64.Моя программа требует, чтобы QueryFullProcessImageName() работал в Vista, но не в XP.
Я пытаюсь загрузить 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, когда указатель функции разыменовывается:
Ошибка проверки во время выполнения № 0 — значение ESP не было должным образом сохранено при вызове функции.Обычно это является результатом вызова функции, объявленной с одним соглашением о вызовах, с указателем функции, объявленным с другим соглашением о вызовах.
Typedef взят прямо из файла .h, поэтому я не могу понять, почему он не работает.Любая помощь?Я перепробовал массу вариантов, но безуспешно.
Решение
Вам следует изменить typedef на
typedef BOOL (WINAPI *LPQueryFullProcessImageName)(
HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize );
WINBASEAPI используется для объявления статических зависимостей и не определяет соглашение о вызовах __stdcall.Вы используете GetProcAddress(), поэтому статическая зависимость вас не интересует, но вам все равно нужен __stdcall для правильного вызова вызова.