9.13(목) 실습-1

from Study/API 2007/10/10 11:18 view 22560
// 1. 가상주소값 알아보기
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);
}



Tag | ,

Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다