int x = 0;
int main()
{
cout << main << endl;
cout << &x << endl;
// Exe의 가상주소를 구한다.( 이값이 instance )
void* p1 = GetModuleHandle(0);
void* p2 = GetModuleHandle("ntdll.dll");
void* p3 = GetModuleHandle("kernel32.dll");
void* p4 = GetModuleHandle("user32.dll");
void* p5 = GetModuleHandle("gdi32.dll");
cout << "exe 주소 : " << p1 << endl;
cout << "ntdll.dll 주소 : " << p2 << endl;
cout << "kernel32.dll 주소 : " << p3 << endl;
cout << "user32 주소 : " << p4 << endl;
cout << "gdi32 주소 : " << p5 << endl;
// 가상주소를 알때 모듈이름을 구하는 함수
char name[256];
GetModuleFileName((HMODULE)0x00400000, name, 256);
cout << name << endl;
// 이 함수는 User32.dll 에 있다.
// 또한 내부적으로 Gdi32.dll의 함수를 사용한다.
MessageBox( 0, "","",MB_OK);
return 0;
}
// 2. DLL의 명시적 연결 : 헤더파일과 .lib 파일이 필요 없다. 단지 DLL만 있으면 된다.
// 단, DLL이 가진 함수의 모양(signaure)는 알아야 한다.
typedef void (*F)(const char* s);
int main()
{
getch();
HMODULE hDll = LoadLibrary( "MyDll.dll" );
if( hDll == 0 )
{
printf("DLL을 찾을 수 없습니다.\n");
return -1;
}
printf("DLL이 Load된 주소 : %p\n", hDll );
//------------------------------------------
// DLL 에서 함수 찾기
F f = (F)GetProcAddress( hDll, "PutStringA" );
if( f == 0 )
printf("PutString 함수가 없습니다.\n");
else
f("AAA");
getch();
FreeLibrary( hDll );
return 0;
}
// 3. 여러가지 이야기
// 링커에게 exe의 종류를 알려준다.
#pragma comment( linker, "/subststem:console" )
// 함수 호출 규약
// __cdecl : 모든 CPU가 지원하는 기계어 코드 생성
// __stdcall : 메모리 사용량이 __cdecl 보다 적다
// __fastcall : 가장 빠르게 동작하는 기계어 생성
// this : C++ 멤버 함수가 호출되는 원리 - this가 ecx로 전달
// naked : 디바이스 드라이버 만들 때 주로 사용 - stack Frame이 생략된다.
// 4. 윈도우 열거(EnumWindows)
BOOL CALLBACK foo( HWND hwnd, LPARAM lParam );
int main()
{
// 모든 Top-Level 윈도우를 열거한다.
EnumWindows(
foo, // Callback 함수
0 ); // 함수의 2번째 인자로 보낼 Data
}
BOOL CALLBACK foo( HWND hwnd, LPARAM lParam )
{
char cname[256];
char title[256];
if ( IsWindowVisible( hwnd ) == FALSE ) return TRUE; // 안보이는 윈도우.
if ( GetWindowTextLength( hwnd ) == FALSE ) return TRUE; // 캡션 글자가 없는경우
// 작업관리자는 바탕화면을 열거 하지 않는다.
// 작업관리자 자신도 열거 하지 않는다.
// 소유된 윈도우도 열거 하지 않는다.(OWNER)
// Getparent() : 부모 또는 소유 윈도우의 핸들을 구한다.
if ( GetParent(hwnd) != 0 ) return TRUE; // 소유된 윈도우 제거
if ( IsWindowVisible( hwnd ) == FALSE ) return TRUE; // 안보이는 윈도우.
GetClassName( hwnd, cname, 256 );
GetWindowText( hwnd, title, 256 );
cout << hex << hwnd << "-" << cname << "-" << title << endl;
return TRUE; // 계속 찾으라는 의미
// 여기서 FALSE를 리턴하면 더이상 열거하지 않는다.
}
// 5. lib를 만들어 보기.
// a.h
// 라이브러리 파일에 있는 모든 함수의 선언을 제공해 준다.
// C++ 에서 사용할 경우를 대비 해야 한다.
#ifdef __cplusplus
extern "C" {
#endif
int Add(int , int);
#ifdef __cplusplus
}
#endif
// a.c
int Add( int a, int b )
{
return a + b;
}
// 빌드하면 DLib.lib 가 만들어진다.
// 6. 정적 라이브러라 사용하기.
// 정적 라이브러리를 사용하는 방법
// 1. 헤더 include
#include "aa.h"
// 2. lib를 링커에게 알려준다.
#pragma comment(lib, "DLib.lib")
int CppAdd( int a, int b )
{
return a + b;
}
int CppAdd( int a, int b, int c )
{
return a + b + c;
}
int main()
{
int n = Add(1, 2);
printf("%d\n", n);
n = CppAdd(1, 2);
printf("%d\n", n);
n = CppAdd(1, 2, 3);
printf("%d\n", n);
}