摘要:以MemoryMappedFile的方式,在.Net程式與原生Dll之間通訊
用.Net來寫視窗程式是最容易的,但遇到一些需考量效能或者舊的Library只支援VC6又
沒有.Net的Wrapper就需要自己寫Wrapper,藉由P/Invoke的方式做溝通。
而MemoryMappedFile則是另一種可行的方式。
依我的例子,我例用VS2010寫介面,並控制所有的硬體,將硬體取得的資料存到MemoryMappedFile中。
而計算的部份就交給VC6寫的dll去執行(因為Library舊,只支援到VC6)。
.Net的部份,其部份程式碼如下:
//建立MemoryMappedFile
_Map = MemoryMappedFile.CreateOrOpen("MyMapFile", Convert.ToInt64(nudCapacity.Value * 0x100000)); //0x100000 = 1MB
//寫入資料
nbsp; }
//用指標的方式,寫入MemoryMap只要約25ms using (MemoryMappedViewAccessor mmva = _Map.CreateViewAccessor(0xA00000, 100 * 0x100000)) {
//陣列、字串等都是參考型別,不能用在CreateViewAccessor.Wrete<Stuctrue T> 中 mmva.Write<ScanData3D>(0, ref data); //寫入第2筆資料 data.Index = 1; data.IndexX = 1; mmva.Write<ScanData3D>(nSize, ref data); //寫入Array資料 unsafe { byte* pByteOriginal = null; try { mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref pByteOriginal); double* pDouble = (double*)pByteOriginal; for (int i = 0; i < nLen; i++) *pDouble++ = HeightData[i]; byte* pByte = (byte*)pDouble; for (int i = 0; i < nLen; i++) *pByte++ = btDataZ[i]; for (int i = 0; i < nLen; i++) *pByte++ = ConfData[i]; for (int i = 0; i < nLen; i++) *pByte++ = IntensityData[i]; } finally { if(pByteOriginal != null) mmva.SafeMemoryMappedViewHandle.ReleasePointer(); } } }
而在VC6的部份
HANDLE hMapFile;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
"MyMapFile"); // name of mapping object
if (hMapFile == NULL)
{
printf(TEXT("Could not open file mapping object (%d).\n"), GetLastError());
return 1;
}
LPVOID mapView = MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
0x300000);
if (mapView == NULL)
{
printf(TEXT("Could not map view of file (%d).\n"), GetLastError());
CloseHandle(hMapFile);
return 1;
}
ScanData3D* pData = NULL;
//pData = new ScanData3D();
//讀出資料
//memcpy(pData, mapView, sizeof(ScanData3D));
pData = (ScanData3D*)mapView;
printf("Size of long = %d\n", sizeof(INT64));
printf("Index = %d\n", pData->Index);
printf("Width = %d\n", pData->Width);
printf("Height = %d\n", pData->Height);
printf("DataBeginPos = %d\n", pData->DataBeginPos);
pData++; //next data
printf("Index = %d\n", pData->Index);
printf("Width = %d\n", pData->Width);
printf("Height = %d\n", pData->Height);
printf("DataBeginPos = %d\n", pData->DataBeginPos);
UnmapViewOfFile(mapView);
CloseHandle(hMapFile);
以上程碼式可能有誤,有需要的人請自行測試囉。
============ 以下是簽名檔 ============
一個小小螺絲釘。
第一次建立Blog,希望以後能慢慢充實它。
Howard