C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[6478] [답변] 빌더에서 메모리맵 사용방법
성낙현 [pasil] 3063 읽음    2001-03-30 23:01
내가 예전에 나우누리 씨빌더 게시판에 올렸던 강좌를 그대로 올려 드립니다. 참고 하세요.
씨빌더에서 메모리맵드 아이오의 사용방법입니다.

...............................


프로그램과 프로그램끼리 통신하는 방법은 참으로 여러가지가 있다.

프로그램이 서로 다른 PC에서 동작되고 있다면 RS232나 TCP/IP 통신으로 정보를 주고

받아야 겠지만, 그렇지 않고 같은 PC내에서 동작되고 있는 프로그램끼리는 DDE나
여러방법이 있겠으나 이중에서 아주 사용법이 간단하고, 신뢰성 높은..

"메모리맵드 파일 아이오 방식"을 소개한다.


1. 왜 메모리맵드 파일 아이오 방식을 사용하여야 하는가?

프로그램을 작성하다보면 프로그램과 프로그램끼리 통신을 해야하는 경우가 상당히
많이 발생한다. 지금 현재 대표적으로 사용하는 방법이 DDE방식이다. 많은 업체의
프로그램들이 서로의 호완성이나 데이타 공유를 위해 DDE방식을 표준화 시켜서
사용하고 있는데.. 사실 DDE를 사용해 본사름은 알겠지만 그리 수월하지만은 않다.
그외에도 OLE,COM이라는 정신 사나운 개념들이 많지만 간단하게 자료를 주고받을때
이렇게 거창한 기법들을 쓰는게 무척이나 부담스럽다. 그리고 자신의 프로그램을
기능별, 모듈별로 분리시켰을 경우, 이를테면 통신만 전담하는넘, 모니터링만 하는넘

설정만 하는넘.. 이렇게 서로 프로그램을 분리 시켰을때 프로그램끼리 서로 통신
해야하는 경우가 발생하는데 이럴때 쉽고 간편하게 쓸수 있는것이 메모리 맵드
아이오를 이용한 통신 방법이다.


2. 프로그램 목표
프로그램을 여러개 띄어 놓고 프로그램에서 읽기, 쓰기를 해본다. 데이타 타입은
정수형과 문자열을 사용한다. 각각의 프로그램애서 서로 데이타가 공유된다.


3. 사용할 API

사실 이넘을 제대로 쓰려면 무지하게 복잡하나 우리의 목표는 단순히 프로그램과
프로그램간의 통신이 목적이니까 자세한 설명은 피하고 우리의 목적에 맞게끔만
코딩해 보겠다. 자세한것을 원하는 사람은 빌더의 헬프파일을 참조해 보시길..
그리고 때로는 너무 자세히 아는것보단 필요한 부분까지만 아는게 시간이 절약된다
^^;;

* 설정 부분

HANDLE CreateFileMapping(

    HANDLE hFile,       // 공유할 아이오맵의 핸들
    LPSECURITY_ATTRIBUTES lpFileMappingAttributes,      // 보안속성
    DWORD flProtect,    // 사용할 맵파일의 속성
    DWORD dwMaximumSizeHigh,    // 사용할 자료의 상위 사이즈
    DWORD dwMaximumSizeLow,     // 사용할자료의 하위 사이즈
    LPCTSTR lpName      // 맵파일의 고유 이름
   );

공유할 아이오맵의 핸들값은 여기서는 공유할일이 엄꼬 우리끼리 쓸것이니깐..
0xFFFFFFFF이라는 값을 주면 된다. (설명서에 그렇게 나와 있다.. -.-;)
보안속성은.. 머.. 멀 그냥 NULL을 주자.. 그냥 그려려니 하자..
맵파일 속성은 읽고 쓰기를 해야하니깐.. PAGE_READWRITE
상위 사이즈는 머.. 그냥 0을 주고..
하위사이즈는 자신이 사용할 자료형의 사이즈를 지정해 준다..
마지막으로 맵파일이름은 여러종류의 맵파일중 특정넘을 가르키는 역활을 하니깐
너무 복잡하지 않도록 지정해 준다.

* 해체부분
BOOL CloseHandle(

    HANDLE hObject      // 해체할 맵파일의 핸들
   );


* 맵파일에 읽고 쓸때 사용하는 부분

LPVOID MapViewOfFile(

    HANDLE hFileMappingObject,  // 맵파일 핸들
    DWORD dwDesiredAccess,      // access mode
    DWORD dwFileOffsetHigh,     // high-order 32 bits of file offset
    DWORD dwFileOffsetLow,      // low-order 32 bits of file offset
    DWORD dwNumberOfBytesToMap  // number of bytes to map
   );

엑세스 모드의 값은 FILE_MAP_WRITE을 준다.
그리고 나머지의 값은 모두 0을 준다.


4. 폼디자인

자 우선 빌더에서 File - New Application 해서 새로운 프로젝트를 연다.

그리고 다음과 같이 디자인 하자..
┌────────────────────────┐
│                                                │
│                                                │
│                                                │ No  VCL        NAME
│       ┌────┬─┐   ┌─────┐        │
│       │1       ├─┤   │2 IntWrite│        │ 1  CSpinEdit  CSpinEdit1
│       └────┴─┘   └─────┘        │
│         CSpinEdit1       ┌─────┐        │ 2  TButton    IntRead
│                          │3 IntRead │        │
│                          └─────┘        │ 3  TButton    IntWrite
│                                                │
│                                                │ 4  TEdit      Edit1
│       ┌──────┐   ┌─────┐        │
│       │4  Edit1    │   │5 StrWrite│        │ 5  TButton    StrWrite
│       └──────┘   └─────┘        │
│                          ┌─────┐        │ 6  TButton    StrRead
│                          │6 StrRead │        │
│                          └─────┘        │
│                                                │
│                                                │
└────────────────────────┘


5. 코딩

* 헤더파일에 추가할것

private에 다음을 추가한다.

    HANDLE FileMapObj;          // 정수값을 저장할 파일 아이오 핸들
    HANDLE StrFileMapObj;   // 문자열을 저장할 파일 아이오 핸들


//---------------------------------------------------------------------------
//  폼 생성
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    // 정수값을 다룰 맵파일
    FileMapObj = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0,
      sizeof(int), "FileIO");

    // 문자열을 다룰 맵파일 버퍼값으로 20을 주었으나 사용자에 맞게 조정한다.
    StrFileMapObj = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE,
       0, 20, "StringFileIO");
}

//---------------------------------------------------------------------------
// 폼해제
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    // 맵파일 해제..
    CloseHandle(FileMapObj);
    CloseHandle(StrFileMapObj);
}

//---------------------------------------------------------------------------
// 정수값을 쓰기위한 함수
//---------------------------------------------------------------------------
void __fastcall TForm1::IntWriteClick(TObject *Sender)
{
    int *p;     //반드시 포인터로 지정.. 머.. 반드시는 아니지만.. ^^;

    p = (int *)MapViewOfFile(FileMapObj, FILE_MAP_WRITE, 0, 0, 0);

    // 만약 p값이 NULL이면 성공하지 못한것 이므로 예외처리를 해준다.
    try {
        *p = CSpinEdit1->Value;
    }
    __finally {
        UnmapViewOfFile(p);
    }
}

//---------------------------------------------------------------------------
// 정수값을 읽기위한 함수
//---------------------------------------------------------------------------
void __fastcall TForm1::IntReadClick(TObject *Sender)
{
    int *p;

    p = (int *)MapViewOfFile(FileMapObj, FILE_MAP_WRITE, 0, 0, 0);

    try {
        // 설명 안해도 되죠? -.-; 넘 기초적인 포인터 사용법..
        ShowMessage(IntToStr(*p));
    }
    __finally {
        UnmapViewOfFile(p);
    }
}

//---------------------------------------------------------------------------
// 문자열값을 읽기위한 함수
//---------------------------------------------------------------------------
void __fastcall TForm1::StringWriteClick(TObject *Sender)
{
    char *p;

    p = (char *)MapViewOfFile(FileMapObj, FILE_MAP_WRITE, 0, 0, 0);

    try {
        strcpy(p, Edit1->Text.c_str());
    }
    __finally {
        UnmapViewOfFile(p);
    }
}

//---------------------------------------------------------------------------
// 문자열값을 읽기위한 함수
//---------------------------------------------------------------------------
void __fastcall TForm1::StringReadClick(TObject *Sender)
{
    char *p;

    p = (char *)MapViewOfFile(FileMapObj, FILE_MAP_WRITE, 0, 0, 0);

    try {
        ShowMessage(p);
    }
    __finally {
        UnmapViewOfFile(p);
    }
}
//---------------------------------------------------------------------------


움.. 끝났습니다.. 사용법이 무지 쉽지만 그 응용범위는 아주 많을꺼라 생각 됩니다.

비록 자세한 설명은 피하고 입맛에 맞는 부분만 했지만 서도요.. ^^;


+ -

관련 글 리스트
6477 [질문] 메모리 멥을 사용하고 싶은데... 남병철 2194 2001/03/30
6478     [답변] 빌더에서 메모리맵 사용방법 성낙현 3063 2001/03/30
6480         Re:Thank you ^^ 방태윤 2175 2001/03/31
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.