[펌: http://blog.naver.com/hsshee?Redirect=Log&logNo=70037637328]
간혹 어떤 프로그램에서 LoadLibrary와 GetProcAddress API를 사용하여,
어떤 dll 내의 함수를 사용하는 경우가 있다.
LoadLibrary와 GetProcAddress의 원형을 살펴보자.
◈ HMODULE LoadLibrary( LPCTSTR lpFileName );
> 인자로 준 DLL을 현재 프로세스의 주소공간으로 mapping 시켜서 사용할 수 있도록 해주는 API.
◈ FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
> DLL에서 Export한 함수의 번지를 찾아서 그 함수를 사용할 수 있도록 그 함수의 포인터를 리턴해 주는 API.
1. DLL 내의 함수를 사용하기 위해서는,
먼저 LoadLibrary를 이용하여 DLL의 모듈 핸들을 리턴 받는다.
( HMODULE or HINSTANCE와 같은 핸들을 통해 리턴받으면 된다. )
인자는 DLL의 경로를 문자열로 넘겨주면 되고, 끝에 널문자가 있어야 한다는 걸 잊지 말자.
참고로, 반드시 리턴된 모듈 핸들이 NULL이 아닌지를 체크하는 습관을 들이도록 하자.
2. 유효한 모듈 핸들을 가지고,
GetProcAddress를 이용하여 DLL에서 Export한 함수를 가져오자.
이 때의 인자는 LoadLibrary를 통해서 리턴 받은 모듈 핸들과
그 DLL 내에서 사용하기 원하는 함수의 이름을 문자열로 넘겨준다. 이 때에도 끝에 널문자가 있어야 한다.
GetProcAddress를 수행하면 프로그램에서 선언한 함수포인터 변수에
DLL에서 Export한 함수의 주소가 리턴되어 이 프로그램에서 선언한 변수를 통하여
DLL 내의 해당 함수를 사용할 수 있게 되는 것이다.
만약에 인자가 정확하게 들어가지 않았다면, 역시 NULL이 리턴된다.
3. LoadLibrary와 같이 모듈 핸들을 받아서 DLL을 사용하였을 경우,
FreeLibrary API를 이용하는 습관을 들이도록 하자.
◈ BOOL FreeLibrary(HMODULE hLibModule);
>해당 DLL의 사용 카운트를 1 감소시키고 사용 카운트가 0이 되었을 때에 메모리에서 해당 DLL을 삭제해준다.
리턴형은 BOOL인데, 이 때에 DLL을 삭제하는 데에 성공했다면 TRUE를, 실패했다면 FALSE를 리턴하는 것이다.
Name Mangling으로 인한 경우가 있다. 이 때의 해결책은 다음과 같다.
DLL 프로그래밍한 프로젝트에서 export하는 함수를 선언하는 헤더에 다음과 같이 추가하여 Rebuild하면 된다.
cpp dll 을 c type으로 바꿔주는 코드
#ifdef __cplusplus
extern "C"
{
#endif
// export할 함수
#ifdef __cplusplus
}
#endif
어떤 함수를 위의 코드를 이용하지 않고 빌드한 경우와 위의 코드를 추가하여 빌드한 경우에
각각의 dll파일을 Peview를 통하여 어떻게 함수명이 저장되는지 확인해보자.
원하는 함수명은 GetOpcodeFirstByte이다.
1) 위의 코드를 이용하지 않고 빌드한 경우,
2) 위의 코드를 추가하여 빌드한 경우,
1)의 경우에 GetProcAddress에서 Export할 함수의 문자열을 "GetOpcodeFisrtByte"로 넘겨주면,
실제 dll의 export된 함수명과 다르기 때문에 NULL이 리턴된다.
※ 위의 코드를 추가하는 습관을 들이도록 하자.
'NativeCode > api' 카테고리의 다른 글
printf, scanf 함수 포맷 문자열 (0) | 2010.07.07 |
---|---|
IP, TCP, UDP, ICMP Checksum 계산 (0) | 2010.07.05 |
IpHlpApi MSDN (0) | 2010.07.04 |
SendARP (0) | 2010.07.03 |
[팁] Heap 메모리 검증하기.. | VC++ 일반 (0) | 2010.05.09 |