關於進程間共用資料的研究。
昨天看了用共用節的方式共用待用資料,但是這個方法安全性不高,而且無法適用於需要動態分配大塊記憶體的情況。
今天嘗試了一下記憶體對應檔,發現可以很好的解決這個問題。
範例:
dll.hclass testFileMapping
{
private:
HANDLE hMapping;
LPVOID lpData;
public:
bool init();
void set(int idx,int val);
int get(int idx);
testFileMapping();
~testFileMapping();
};
MY_API HANDLE InitFileMapping();
MY_API void SetFileMapping(HANDLE hMap,int idx,int val);
MY_API int GetFileMapping(HANDLE hMap,int idx);
MY_API void CleanFileMapping(HANDLE hMap);
dll.cpp
bool testFileMapping::init()
{
hMapping=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,sizeof(int)*100,L"MYSHARE");
if(hMapping==NULL)
{
return false;
}
lpData=MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0);
if(lpData==NULL)
{
return false;
}
}
void testFileMapping::set(int idx, int val)
{
int* tp = (int*)lpData;
tp[idx] = val;
}
int testFileMapping::get(int idx)
{
int* tp = (int*)lpData;
return tp[idx];
}
testFileMapping::testFileMapping()
{
hMapping = NULL;
lpData = NULL;
}
testFileMapping::~testFileMapping()
{
if(NULL != lpData)
{
UnmapViewOfFile(lpData);
lpData = NULL;
}
if(NULL != hMapping)
{
CloseHandle(hMapping);
hMapping = NULL;
}
}
MY_API HANDLE InitFileMapping()
{
testFileMapping* tp = new testFileMapping();
tp->init();
return tp;
}
MY_API void SetFileMapping(HANDLE hMap,int idx,int val)
{
((testFileMapping*)hMap)->set(idx,val);
}
MY_API int GetFileMapping(HANDLE hMap,int idx)
{
return ((testFileMapping*)hMap)->get(idx);
}
MY_API void CleanFileMapping(HANDLE hMap)
{
delete ((testFileMapping*)hMap);
}
編譯為dll後,在不同的程式中調用,就可以共用一塊大小為100的int數組。因為沒有加邊界控制,所以檢查了一下邊界條件,發現其實可以訪問的記憶體是大小為1024的int數組,也就是x86分頁檔的大小4KB。當然這樣的訪問是不安全的,應該在程式中加以屏蔽。