|
빌더에서 사용할 수 있는 간단한 공유메모리 사용법이 궁금합니다.
유닉스에서는 공유메모리를 사용했었는데..
함수가 다르고 여러가지 사용법이 다른거 같더군요.
간단한 예제..
공유메모리를 만들고, 저장하고,
해제하고 다른 프로세스에서 접근하고 읽는..
제가 쓰는 방법을 조금 알려드리죠.
밑에 마법감자님이 설명한데로 하면 되는데
좀 더 자세하게 설명을 한다면
=ㅅ= 같은 경우에는 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 호출하는 식으로 공유메모리에
접근하자는
것이죠
|
관련 글 리스트
|
이에 대한 해결책은 다음의 문서를 참조하세요.
http://bdn.borland.com/article/0,1410,20132,00.html