티스토리 뷰

프로그래밍/API

API 메모리 맵 파일

에어버스 2016. 5. 6. 12:08

메모리 맵 파일

하드디스크에 있는 파일을 가상 메모리 주소 공간에 직접 매핑하여 파일을 메모리처럼 사용하는 기법

실행파일(*.exe)과 DLL 등과 같이 무거운 실행파일을 메모리에 로드할 필요없이 바로 가상메모리로 매핑해서 실행하도록하면 유용하다. 그래서 대용량 가상메모리 할당 또는 대용량 파일처리에 적합하다.
또한, 동일한 메모리 맵 파일을 이용하여 프로세스간 데이타 공유 가능하다.

1. 파일 매핑 객체 생성

HANDLE CreateFileMapping(
  HANDLE 메모리에 매핑할 대상 파일의 핸들,
  LPSECURITY_ATTRIBUTES 보안속성, // 보통 NULL
  DWORD 접근속성,
  DWORD 파일 매핑에 사용할 메모리 길이 중 상위 32비트, // 0
  DWORD 파일 매핑에 사용할 메모리 길이 중 하위 32비트,
  LPCTSTR 파일 매핑 객체 이름); // 필요하지 않을 경우 NULL

<접근속성>

PAGE_READONLY
PAGE_READWRITE
PAGE_WRITECOPY    페이지에 쓸 경우 복사본을 만듬
PAGE_COMMIT        기본값으로 하드디스크 또는 메모리상의 모든 파일 영역을 할당
PAGE_IMAGE           char* 형과 같다
PAGE_NOCACHE      실행 이미지 파일을 매핑하고 캐시를 사용하지 않음
PAGE_RESERVE        물리적 메모리를 직접 사용하지 않고 보류(Recerved) 상태로 설정할 수
                           실제 메모리를 사용하지 않으나 다른 응용 프로그램이 사용할 수 없다


<파일 매핑에 사용할 메모리 길이 중 상위 32비트>

32비트 체제에서는 상위 32비트는 참조되지 않기 때문에 이 값은 항상 0 이고
파일 매핑에 사용할 메모리 길이 중 하위 32비트만 사용한다.

<파일 매핑 객체 이름>

복수개의 프로세스가 하나의 파일 매핑 객체를 공동으로 사용할때 사용
서로 다른 프로세스에서 같은 파일 매핑 객체를 얻기 위한 이름을 약속할 때 사용한다.

2. 주소 공간에 매핑

LPVOID MapViewOfFile(
  HANDLE 가상 주소공간에 매핑하려는 파일 매핑 객체의 핸들,
  DWORD 접근속성,
  DWORD 매핑을 시작할 오프셋 위치 상위32비트,
  DWORD 매핑을 시작할 오프셋 위치 하위32비트, // 0 : 파일 전체 매핑, 일부만 매핑할 경우 값 지정
 
DWORD 매핑할 뷰의 크기);

<접근속성>

FILE_MAP_WRITE
FILE_MAP_READ
FILE_MAP_ALL_ACCESS    읽기/쓰기
FILE_MAP_COPY            읽기/쓰기, 쓸때 복사본을 만든 후 쓴다

3. 매핑 파일 닫기

UnmapViewOfFile(LPCVOID 매핑파일포인터);

CloseHandle(HANDLE 매핑파일핸들);

CloseHandle(HANDLE 파일핸들);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    TCHAR* pFile;
    HANDLE hFile, hMapFile;
    RECT rect;
 
    TCHAR fileData[] = L"서시\r\n\r\n\r\n윤동주\r\n\r\n죽는날까지 하늘을 우러러\r\n한 점 부끄럼없기를\r\n잎새는 이는 바람에도";
    DWORD numOfByteWritten = 0;
 
    switch (message)
    {
    case WM_LBUTTONDOWN:
        hdc = GetDC(hWnd);
        hFile = CreateFile(L"overture.txt", GENERIC_ALL | FILE_MAP_ALL_ACCESS, 0NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        WriteFile(hFile, fileData, sizeof(fileData), &numOfByteWritten, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
            MessageBox(hWnd, L"파일이 없습니다.", L"에러", MB_OK);
        else
        {
            hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 00NULL);
            pFile = (TCHAR*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 00NULL);
            SetRect(&rect, 1010500400);
            DrawText(hdc, pFile, GetFileSize(hFile, NULL), &rect, DT_EXPANDTABS);
            UnmapViewOfFile(pFile);
            CloseHandle(hMapFile);
            CloseHandle(hFile);
        }
        ReleaseDC(hWnd, hdc);
        break;
 
cs


<프로세스간 통신(공유)>

두 프로그램간 통신을 위해 공유할 메모리 맵 객체 이름(SHAREDMAP)을 사용
파일을 공유하는것보다 페이징 파일을 이용하기 위해 INVALID_HANDLE_VALUE 를 사용

두 파일 소스는 동일하고, FindWindow()로 찾을 창의 제목(MemEx/MemSahred)만 다르다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// MemShared
#define ID_EDIT    1000
#define WM_SHARED_MEM    WM_USER+1
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HWND hEdit;
    static TCHAR* pFile = NULL;
    HANDLE hMapFile;
    HWND hTarget;
 
    switch (message)
    {
    case WM_CREATE:
        hEdit = CreateWindow(L"edit"NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE, 1010500200, hWnd, (HMENU)ID_EDIT, hInst, NULL);
        SendMessage(hEdit, EM_LIMITTEXT, 10240);
        hMapFile = CreateFileMapping(INVALID_HANDLE_VALUENULL, PAGE_READWRITE, 01024L"SHAREDMEM");
        pFile = (TCHAR*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 001024);
        break;
    case WM_SHARED_MEM:
        SetWindowText(hEdit, pFile);
        break;
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 메뉴 선택을 구문 분석합니다.
            switch (wmId)
            {
            case ID_EDIT:
                switch (HIWORD(wParam))
                {
                case EN_CHANGE:
                    GetWindowText(hEdit, pFile, 1024);
                    hTarget = FindWindow(NULL, L"MemEx"); // 윈도우 타이틀이 MemEx 인 창을 찾음
                    if (hTarget)
                        SendMessage(hTarget, WM_SHARED_MEM, 00); // 사용자 정의 메시지 전달
                    break;
                }
                break;
    case WM_DESTROY:
        UnmapViewOfFile(pFile);
        PostQuitMessage(0);
        break;
 
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// MemEx
#define ID_EDIT    1000
#define WM_SHARED_MEM    WM_USER+1
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HWND hEdit;
    HDC hdc;
    static TCHAR* pFile = NULL;
    HANDLE hMapFile;
    HWND hTarget;
 
    switch (message)
    {
    case WM_CREATE:
        hEdit = CreateWindow(L"edit"NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE, 1010500200, hWnd, (HMENU)ID_EDIT, hInst, NULL);
        SendMessage(hEdit, EM_LIMITTEXT, 10240);
        hMapFile = CreateFileMapping(INVALID_HANDLE_VALUENULL, PAGE_READWRITE, 01024L"SHAREDMEM");
        pFile = (TCHAR*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 001024);
        break;
    case WM_SHARED_MEM:
        SetWindowText(hEdit, pFile);
        break;
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 메뉴 선택을 구문 분석합니다.
            switch (wmId)
            {
            case ID_EDIT:
                switch (HIWORD(wParam))
                {
                case EN_CHANGE:
                    GetWindowText(hEdit, pFile, 1024);
                    hTarget = FindWindow(NULL, L"MemShared");
                    if (hTarget)
                        SendMessage(hTarget, WM_SHARED_MEM, 00);
                    break;
                }
                break;
    case WM_DESTROY:
        UnmapViewOfFile(pFile);
        PostQuitMessage(0);
        break;
 
cs


 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31