2011-08-14 6 views
3

나중에 SetWindowsHookEx() 함수를 사용하여 일부 프로세스에 삽입하려는 DLL을 빌드하려고합니다. 이상한 점은 DLL을로드하려고 할 때 GetProcAddress를 사용하여 그 안에 포함 된 프로 시저의 주소를 얻으려고하면 CBT 메시지 처리 절차의 주소를 얻으려고하면 NULL을 반환하지만 다른 기능들.GetProcAddress()를 사용하여 DLL에서 일부 함수를로드 할 수 없습니다.

이것은 코드입니다.

DLL HEADER (.H)

#include <windows.h> 

extern "C" { 
    __declspec(dllexport) LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam); 
    __declspec(dllexport) int add(int a, int b); 
} 

DLL 파일 (cpp를) 내가 GetL를 사용하는 경우

#include "SimpleHook.h" 

extern "C" { 
    __declspec(dllexport) LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam) { 
     return CallNextHookEx(0, code, wParam, lParam); 
    } 

    __declspec(dllexport) int add(int a, int b) { 
     return a + b; 
    } 
} 

기본 파일

#include <iostream> 
#include <windows.h> 
#include <tchar.h> 

int main(int argc, char* argv[]) { 
    HINSTANCE dllHandle = LoadLibrary(_T("SimpleHook.dll")); 

    if (dllHandle) { 
     // returns the correct address 
     cout << "add address: " << GetProcAddress(dllHandle, "add") << endl; 

     // returns NULL 
     cout << "hookProc address: " << GetProcAddress(dllHandle, "hookProc") << endl; 
    } 
} 

astError() 의미가있는 127 오류 코드가 나타납니다.

ERROR_PROC_NOT_FOUND : 지정된 프로 시저를 찾을 수 없습니다.

이상한 점은 동일한 파일의 다른 기능이 올바르게로드된다는 것입니다. 도움을 주시면 대단히 감사하겠습니다!

답변

5

호출 규칙은 이름 변환을 변경합니다. __stdcall 함수는 항상 이름 앞에 _을 붙이고 일부 다른 방법으로도 맹 글링하므로 링크가 실패하지만 __cdecl 함수가 엉망이므로 함수를 찾지 못합니다.

당신이 __declspec(dllexport)로 만든 DLL에서 가져 오려면 항상은 당신이 DLL을 건물에서 얻은 LIB를 가져오고 연결하려는 모든에 __declspec(dllimport)와 헤더를 포함해야한다. 이렇게하면 모든 함수가 올바르게 링크되고 C 호환 링크로 이동하지 않아도됩니다.

과 함께 GetProcAddress 또는 extern "C"을 사용하면 안됩니다.

헤더 :

#include <windows.h> 

#ifndef MAIN 
#define DLL_API __declspec(dllexport) 
#else 
#define DLL_API __declspec(dllimport) 
#endif 

DLL_API LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam); 
DLL_API int add(int a, int b); 

DLL의 .cpp 파일 :

#include "SimpleHook.h" 

DLL_API LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam) { 
    return CallNextHookEx(0, code, wParam, lParam); 
} 

DLL_API int add(int a, int b) { 
    return a + b; 
} 

홈페이지 .cpp 파일 :

#define MAIN 
#include "SimpleHook.h" 

int main(int argc, char* argv[]) { 

    if (dllHandle) { 
     // returns the correct address 
     cout << "add address: " << add << endl; 

     // returns NULL 
     cout << "hookProc address: " << hookProc << endl; 
    } 
} 

는 링커에 lib 디렉토리를 추가하는 것을 잊지 마십시오.

+0

이렇게하면 GetProcAddress가 얼마나 정확하게 작동합니까? –

+0

@Ben Voigt :'__cedcl' 함수는 전혀 엉망이 없기 때문에. 제 요점은 그가 GetProcAddress를 사용하지 않아야한다는 것입니다. – Puppy

+0

모든 상황에서 단순히'GetProcAddress' 사용을 피할 수는 없습니다. 또한 맹목적으로 호출 규칙을 변경할 수 없습니다. –

1

맹 글링 된 이름을 확인하려면 dumpbin 또는 종속성 워커와 같은 도구를 사용해야합니다.

또는 연결할 때 DEF 파일을 사용하여 선택한 이름을 내보내기 테이블에 넣을 수 있습니다.

3

CALLBACK 매크로는 __stdcall으로 해석됩니다.따라서 밑줄 문자를 앞에두고 함수 이름에 인수의 크기를 추가해야합니다.

cout << "hookProc address: " << GetProcAddress(dllHandle, "[email protected]") 
    << endl; 
관련 문제