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

C++빌더 FAQ
C++Builder Programming FAQ
[51] 공유메모리 사용법
김성진.kark [kark] 23720 읽음    2002-07-11 22:55
>> 질문 :  나그네 님 ( C++ Builder Q&A 게시판 19993번  )
 
 
빌더에서 사용할 수 있는 간단한 공유메모리 사용법이 궁금합니다.

유닉스에서는 공유메모리를 사용했었는데..

함수가 다르고 여러가지 사용법이 다른거 같더군요.

간단한 예제..

공유메모리를 만들고, 저장하고, 해제하고  다른 프로세스에서 접근하고 읽는..

 
>> 답변1 : 마법감자(magicptt)님  ( C++ Builder Q&A 게시판 20000번 )
 
 
 
>> 답변2 : 에보니.^ㅅ^  (motalpain)   ( C++ Builder Q&A 게시판 20016번 )
 
제가 쓰는 방법을 조금 알려드리죠.

밑에 마법감자님이 설명한데로 하면 되는데

좀 더 자세하게 설명을 한다면 =ㅅ= 같은 경우에는 DLL 의 공유 데이터 영역에 공유메모리를 만들어

그걸 읽었다 썼다 하면서 작업을 함니다. 욜라 빠르고 편합니다.

걍 코드가 나갑니다. =ㅅ=;;

일단 아래와 같은 구조체 자료형을 공유데이터로 쓰고자할때.... 헤더파일을 보면

#ifndef SHAREDDATAH
#define SHAREDDATAH

// =ㅅ=;; 의 소환수인 컴파일러가 길을 잃지 않게 해준다....=ㅅ=;;

/****************************************************************************

           메모리맵에서의 DLL 공유 데이타 자료형

****************************************************************************/

typedef struct TMemoryMappedDLLData
{
  double Data[10];
  double TData[10];
  int      NoInSections[2];
  char    *GPIBStr[2][20];
  char    *RawData;
  int      FilteredDataNo;
  double Parameter[5];
} TSharedData;

static const char *MMFileName = "MEMORY_MAPPED_MORTALPAIN";

#endif

자 그럼 이것을 DLL 의 공유 데이타 영역에 올려서 =ㅅ=;; 에게 쫒긴 배고프고 목마른 프로세스들

이 겨와서 먹고 마시게 해줍니다.... 작은 프로세스야 이리 들어와 편히 쉬어라~ =ㅅ=;;

자 이번엔 옹달샘을 만들어죠... DLL 의 내부코드입니다.

//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#pragma hdrstop

/******************************************************************************

           DLL 내부의 함수 조율 지시자.

******************************************************************************/

#ifdef __DLL__
#define DLL_FUNC __declspec(dllexport)
#else
#define DLL_FUNC __declspec(dllimport)
#endif

#include "SharedData.h"

#pragma data_seg(".Shared")   <--- 착한 꼬마가 프로세스 여럿을 대접하게 한다... =ㅅ=;;

TSharedData *SharedData = NULL;

int SharedDataCount = 0;

#pragma data_seg()

HANDLE         MapHandle;

/*****************************************************************************

           익스포트할 함수들.

*****************************************************************************/

extern "C" DLL_FUNC void __stdcall SetSharedData(TSharedData *ASharedData);
extern "C" DLL_FUNC TSharedData *__stdcall GetSharedData();
extern "C" DLL_FUNC int   __stdcall GetSharedDataCount();

#pragma argsused

TSharedData *__stdcall GetSharedData()
{
  return SharedData;
}

void __stdcall SetSharedData(TSharedData *ASharedData)
{
  SharedData = ASharedData;
}

int __stdcall GetSharedDataCount()
{
  return SharedDataCount;
}

/*

  메모리 맵을 생성한다.

*/

void CreateSharedData()
{
  int size = sizeof(TSharedData);

  MapHandle = CreateFileMapping((HANDLE)0xFFFFFFFF,
                                               NULL,
                                               PAGE_READWRITE,
                                               0,
                                               size,
                                               MMFileName);

  if ( MapHandle == NULL )
  {
     ShowMessage("Unable to create file mapping !");
     return;
  }

  SharedData = (TSharedData *)MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, size);

  if ( SharedData == NULL )
  {
     CloseHandle(MapHandle);
     ShowMessage("Unable to map view of file. Error : " + GetLastError());
  }
}

/*

  메모리 맵에 매핑된 공유 데이터를 연다.

*/

void OpenSharedData()
{
  int size = sizeof(TSharedData);

  MapHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, MMFileName);

  if ( MapHandle == NULL )
  {
     ShowMessage("Unable to Open file mapping !");
     return;
  }

  SharedData = (TSharedData *)MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, size);

  if ( SharedData == NULL )
  {
     CloseHandle(MapHandle);
     ShowMessage("Unable to map view of file. Error : " + GetLastError());
  }
}

/*

  공유된 메모리맵과 핸들을 닫는다.

*/

void CloseSharedData()
{
  UnmapViewOfFile(SharedData);
  CloseHandle(MapHandle);
}

/*

  공유된 메모리맵의 데이터를 초기화 한다.

*/

void InitSharedData()
{
  for ( int i = 0; i <= 1; ++i )
  {
     SharedData->NoInSections[i] = 0;
  }

  for ( int i = 0; i <= 1; ++i )
  {
     for ( int j = 0; j <= 19; ++j )
     {
        SharedData->GPIBStr[i][j] = "";
     }
  }

  SharedData->RawData = "";
  SharedData->FilteredDataNo = 0;

  for ( int i = 0; i <= 9; ++i )
  {
     SharedData->Data[i]   = i;
     SharedData->TData[i] = 0;
  }

  SharedData->Parameter[0] = 0.2;
  SharedData->Parameter[1] = 5.0;
  SharedData->Parameter[2] = 0.7;
  SharedData->Parameter[3] = 0.5;
  SharedData->Parameter[4] = 0;
}

/*

  DLL 엔트리 포인트 함수

*/

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  switch(reason)
  {
     case DLL_PROCESS_ATTACH :          // 프로세스가 이 DLL을 자기 공간으로 매핑할 때

        if ( SharedDataCount == 0 )    // 대신 CreateFileMapping 의 에러 반환 값인
        {                                           // ERROR_ALREADY_EXIST 를 이용 가지를 쳐도 상관엄따....
           CreateSharedData();             // Win32 DLL 의 특성상 자체 레퍼런스 카운트가 있으나
           SharedDataCount ++;             // 이해를 돕기위해 채택... =ㅅ=;;
           InitSharedData();
        }
        else
        {
           OpenSharedData();
           SharedDataCount ++;
        }
        break;

     case DLL_PROCESS_DETACH :          // 프로세스가 이 DLL을 자기 주소 공간에서 언맵할 때

        CloseSharedData();
        SharedDataCount --;
        break;
  }

  return true;
}
//---------------------------------------------------------------------------

요는 일일이 프로세스 마다 CreateFileMapping 쓰지말고 DLL 호출하는 식으로 공유메모리에

접근하자는 것이죠

김상구.패패루 [peperu]   2005-04-06 14:01 X
C++ Builder에서는 #pragma data_seg를 지원하지 않습니다.
이에 대한 해결책은 다음의 문서를 참조하세요.
http://bdn.borland.com/article/0,1410,20132,00.html

+ -

관련 글 리스트
51 공유메모리 사용법 김성진.kark 23720 2002/07/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.