2013-11-23 3 views
1

Прежде всего да, я искал это какое-то время и не может найти ответы , относящийся к моему делу. В основном я пытаюсь получить адрес функции в Windows DLL (dnsapi.dll), а GetProcAddress возвращается 0. Через некоторое время царапая голову, я даже начал создавать программу, которая просто использует GetProcAddress MessageBox в user32. длл. Тот же результат. Вот код второй программы я сделал, который до сих пор не работает:GetProcAddress возвращает 0 Для всех функций

#include <stdio.h> 
#include <Windows.h> 

int main() { 
    HINSTANCE hLib = LoadLibrary(TEXT("user32.dll")); 
    DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBox"); 

    printf("%ld", MsgBoxAddr); 
    getchar(); 

    return 0; 
} 

BTW GetLastError возвращает 127, который, кажется, самая распространенная ошибка возвращается, когда GetProcAddress не работает, но я не могу понять что не так, я пробовал со многими функциями и DLL, а не только с этими парами.

Спасибо. :)

EDIT: Связанная статья решила мою проблему, функции, которые я пробовал, имели версии unicode и anis (w и a). Использование полных имен API решило проблемы. Спасибо, что связали этот вопрос.

спасибо.

ответ

5

Некоторые распространенные API-интерфейсы не являются настоящими именами функций, включая LoadLibrary, GetProcAddress и MessageBox. Все эти функции не существуют!

Это потому, что Windows API, которые принимают текст как параметр, будут иметь две версии каждой, которая принимает текст ANSI и другие, которые принимают текст UNICODE. Эти «функции», которые вы знаете, на самом деле - макросы препроцессора, которые автоматически перенаправят вас в нужную функцию в зависимости от вашей стандартной кодировки проекта Visual Studio.

MessageBox например, не существует. Существуют функции MessageBoxA и MessageBoxW, один для ANSI для UNICODE. Так что это, как вы получите свой адрес:

ANSI:

HINSTANCE hLib = LoadLibraryA("user32.dll"); 
DWORD MsgBoxAddr = (DWORD)GetProcAddressA(hLib, "MessageBoxA"); 

UNICODE:

HINSTANCE hLib = LoadLibraryW(L"user32.dll"); 
DWORD MsgBoxAddr = (DWORD)GetProcAddressW(hLib, L"MessageBoxW"); 

Automatic:

HINSTANCE hLib = LoadLibrary(TEXT("user32.dll")); 
#ifdef UNICODE 
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, TEXT("MessageBoxW")); 
#else 
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, TEXT("MessageBoxA")); 
#endif 
2

Havenard уже дал ответ, так что не» я принимаю мои (но читаю).

Лучший способ решить это определить:

#ifndef _CRT_STRINGIZE // Might be already defined in crtdefs.h, but if not... 
#define __CRT_STRINGIZE(Value) #Value 
#define _CRT_STRINGIZE(Value) __CRT_STRINGIZE(Value) 
#endif 

, а затем использовать

GetProcAddress(hLib, TEXT(_CRT_STRINGIZE(MessageBox))); 
+1

+1 приятно :) '/ * Комментарий должен быть не менее 15 символов в длину. */' – Paul

Смежные вопросы