'explicit'에 해당되는 글 2건

  1. 2009.04.24 DLL 제작 (Explicit)
  2. 2009.04.23 DLL 이란...
2009. 4. 24. 15:02

DLL 제작 (Explicit)



DLL을 명시적(Explicit)으로 연결하기 위한 방법이다.
명시적(Explicit) 연결이라는 부분에 대해서는 프로그램이 실행되고 있는 도중에 필요한 함수가 포함된 DLL을 로드하는 방식이라고 보면 될 듯하다.

명시적인 연결을 위한 DLL을 제작할 때 중요한 함수들이 있다.
HINSTANCE LoadLibrary(LPCTSTR lpLibFileName);
지정한 DLL을 메모리로 읽어와 현재 프로세스의 주소공간에 맵핑시켜 사용할 수 있도록 한다. 하지만, 이미 다른 프로세스에서 해당 DLL을 사용하고 있다면, DLL을 메모리로 또다시 올리는 것이 아니고 DLL 의 사용 카운트만 1 증가시킨다.
인수는 읽고자 하는 DLL 의 파일 이름이다. 파일의 경로를 지정할 수도 있고, 지정하지 않을 수도 있다. 파일의 경로를 지정하지 않으면 DLL을 찾는 순서에 따라 경로를 뒤져가며 해당 DLL을 찾게 된다.

FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
DLL에서 엑스포트한 함수의 번지를 찾아 그 함수의 함수 포인터를 리턴한다.
첫 번째 인수는 함수가 포함된 DLL의 모듈 핸들이며 LoadLibrary() 가 리턴한 값이다.
두 번째 인수는 찾고자 하는 함수 이름이다.
이 함수가 리턴한 함수포인터를 사용하여 DLL에 있는 함수를 호출한다.

BOOL FreeLibrary(HMODULE hLibModule);
DLL의 사용 카운트를 1 감소시키며 사용 카운트가 0이 되었을 경우 메모리에서 DLL을 삭제한다.
첫 번째 인수는 LoadLibrary()가 리턴한 DLL의 모듈 핸들이다. LoadLibrary()로 DLL을 읽어왔다면 반드시 프로세스를 종료하기 전에 FreeLibrary()를 호출하여 DLL을 해제해야 한다.


DLL 제작
DLL 제작 방법은 아래를 참조하면 될듯.. -_-;;
http://todayis.tistory.com/206

DLL Test 프로그램(명시적 연결) 제작
새로운 Win32 프로젝트를 생성하고, WndProc 소스 부분을 아래와 같이 굵은 글자로 된 부분을 추가한다.
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    HINSTANCE hInst;
    int(*pFunc)(int, int);
    TCHAR str[128];

    switch (iMessage) {
    case WM_CREATE:
        hWndMain=hWnd;
        return 0;
    case WM_PAINT:
        hdc=BeginPaint(hWnd, &ps);
        hInst = LoadLibrary(L"DLL_test.dll");
        pFunc = (int(*)(int, int))GetProcAddress(hInst, "AddInteger");
        wsprintf(str, L"1+2 = %d", (*pFunc)(1, 2));
        TextOut(hdc, 10, 10, str, lstrlen(str));
        FreeLibrary(hInst);
        EndPaint(hWnd, &ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

컴파일.. 하고 실행을 하면.. 전에 설명했던 암시적(Implicit) 연결과 동일한 결과임을 알 수 있다.

단지 명시적 연결의 경우 원하는 위치에서 DLL을 직접 호출하는 구문이 있다는 것이다. 위의 경우에는 WM_PAINT
DLL을 사용하는 프로그램이 실행될 때 DLL이 같이 로드되는 것이 아니기 때문에 Settings에 따로 XXX.lib를 지정할 필요가 없다. 또 함수포인터로 함수가 있는 번지를 직접 조사한 후 그 주소를 이용하기 때문에 함수의 원형같은 것도 필요가 없다.
어떻게 보면, 명시적인 연결을 사용하는 DLL 이 더 쉬운듯 하다.

추가로 에러를 위한 처리구문을 추가하자.
LoadLibrary() 그리고 GetProcAddress() 등의 함수를 사용하는 부분을 아래와 같이 처리해 주면 된다.
if((hInst = LoadLibrary(L"DLL_test.dll")) == NULL) {
    MessageBox("There are no DLLs!!!");
    // 추가적인 에러 처리
    return 0;
}
if((pFunc = (int(*)(int, int))GetProcAddress(hInst, "AddInteger")) == NULL) {
    MessageBox("Where is The Function what I want to?? ");
    // 추가적인 에러처리
    return 0;
}


명시적(Explicit) 연결의 장점
1. 필요할 때만 DLL을 읽어와 사용하므로 메모리와 리소스가 절약된다.
2. 상황에 따라 사용할 DLL을 교체할 수 있다.
3. 필요한 DLL이 없는 경우라도 프로그램을 실행할 수는 있다. DLL을 사용하는 부분에서는 정상적인 동작을 안하더라도...
4. DLL을 호출하는 프로그램의 시작 실행속도가 빠르다.

명시적(Explicit) 연결의 단점
1. 사용하기 전에 DLL을 메모리로 읽어오므로 함수 호출 속도가 느리다.

  • 윈도우즈 API 완전정복 참고...


'Programmings > Windows Programming' 카테고리의 다른 글

GetModuleFileNameEx()  (0) 2009.05.15
DllMain  (0) 2009.04.27
DLL 제작 (Implicit 연결)  (0) 2009.04.23
DLL 이란...  (0) 2009.04.23
아스키 코드표  (0) 2009.03.03
2009. 4. 23. 18:30

DLL 이란...



DLL(Dynamic Link)라는 것.. 동적 링크라고도 하는 이넘은... 컴파일시 함수의 코드가 실행 파일에 그대로 복사되는 것이아니고, 실행되는 파일이 실행 될 때 필요로 하는 함수가 실행 파일에 연결되는 형식이다. 실행파일은 단지 호출할 함수의 정보만 포함되고 실제 함수코드는 복사되지 않기 때문에 실행 파일의 크기가 작아진다. 하지만 실행시킬 루틴이 필요하기 때문에 실행파일은 실행시킬 함수에 대한 정보를 가지고 있어야하고, 실행시킬 함수는 DLL 파일의 형태로 존재하게 된다.

장점
1. 한 코드를 여러 프로그램이 같이 사용하기 때문에 메모리가 절약된다.
2. DLL을 사용하는 프로그램은 실행파일 자체에 해당 함수가 포함되지 않기에 크기가 작다.
3. 함수의 루틴을 바꾸고자(업그레이드) 할 경우 해당하는 DLL만 수정하면 된다.
...
이외에도 많은 장점들이 있는듯함..

단점
1. DLL 없이 실행프로그램 자체만으론 동작을 안한다. -_-;
2. DLL 이 교체되거나 하면, 프로그램이 정상동작을 안할 수도 있다.
... 등등..

DLL 연결 방법
1. 암시적(Implicit) 연결

함수가 어느  DLL에 있는지 밝히지 않고 그냥 사용을 하는 방법이다. DLL을 사용하려는 프로젝트는 해당 dll과 lib를 포함하고 있어야 하고, 윈도우즈는 임포트 라이브러리의 정보를 참조해서 해당 DLL을 로드하고 함수를 찾게 된다.
프로그램이 실행될 때 DLL이 로드되므로 실행시 연결(Load time Linking)이라고 한다.
2. 명시적(Explicit) 연결
어느 DLL에 있는 함수인지를 밝히고 사용하는 방법이다. 프로그램이 실행될 때 DLL이 로드되는 것이 아니라 로드하라는 명령이 있을 때만 해당 DLL이 로드된다. 함수가 속해있는 DLL의 이름을 명시적으로 지정하여 호출하므로 임포트 라이브러리는 필요하지 않다.
프로그램이 실행 중에 DLL이 메모리로 읽혀지기 때문에 실행중 연결(Run Time Linking)이라고 한다.