Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools


Memory-mapped files provide a way to look at a file as a chunk of memory. This feature is very useful in languages that support examining memory at arbitrary addresses. You map the file and get back a pointer to the mapped memory. You can simply read or write to memory from any location in the file mapping, just as you would from an array. When you’ve processed the file and closed the file mapping.

Here is the basic steps to share data between different processes

- Create a memory mapped file using CreateFileMapping API which will return a handle to memory mapped file.
- After you get valid file handle from CreateFileMapping you can call MapViewOfFile to map entire file into your process address space. If MapViewOfFile call is successful then it will return memory address of shared memory location.
- You can now write or read data to the the shared memory location.
- Call UnmapViewOfFile if you dont need shared memory anymore.

Note : You can use OpenFileMapping function to get handle of existing shared memory file.

Click here to copy the following block
Option Explicit

' Arbitrary name for the file mapping.
Const sMapName = "TestSharedMap"

Const offset_intSharedData = 0  '//first element in the shared memeory is integer data
Const offset_lngSharedData = 2  '//second element in the shared memeory is long integer
Const offset_boolSharedData = 6  '//third element in the shared memeory is boolean value
Const offset_bytArrSharedData = 7  '//fourth element in the shared memeory is byte array
Const offset_strSharedData = 13  '//fifth element in the shared memeory is string

Const PAGE_READONLY As Long = &H2
Const PAGE_READWRITE As Long = &H4
Const PAGE_WRITECOPY As Long = &H8

Const FILE_MAP_COPY As Long = 1
Const FILE_MAP_WRITE As Long = 2
Const FILE_MAP_READ As Long = 4
Const FILE_MAP_ALL_ACCESS As Long = FILE_MAP_WRITE

Const INVALID_HANDLE_VALUE As Long = -1

'//////////////////////////////////////////////////

Private Declare Function OpenFileMapping Lib "kernel32" Alias "OpenFileMappingA" ( _
    ByVal dwDesiredAccess As Long, _
    ByVal bInheritHandle As Long, _
    ByVal lpName As String) As Long

Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" ( _
    ByVal hFileMapTable As Long, _
    ByVal lpFileMappingAttributes As Long, _
    ByVal flProtect As Long, _
    ByVal dwMaximumSizeHigh As Long, _
    ByVal dwMaximumSizeLow As Long, _
    ByVal lpName As String) As Long

Private Declare Function MapViewOfFile Lib "kernel32" ( _
    ByVal hFileMapTableMappingObject As Long, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwFileOffsetHigh As Long, _
    ByVal dwFileOffsetLow As Long, _
    ByVal dwNumberOfBytesToMap As Long) As Long

Private Declare Function UnmapViewOfFile Lib "kernel32" ( _
    lpBaseAddress As Any) As Long

Private Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long

Private Declare Sub CopyMemoryWrite Lib "kernel32" Alias "RtlMoveMemory" ( _
    ByVal Dst As Long, _
    pSrc As Any, _
    ByVal ByteLen As Long)  ' Src -> *(Dst)

Private Declare Sub CopyMemoryRead Lib "kernel32" Alias "RtlMoveMemory" ( _
    pDst As Any, _
    ByVal Src As Long, _
    ByVal ByteLen As Long)  ' *(Src) -> Dst

'//Variables to hold shared data
Dim intSharedData As Integer
Dim lngSharedData As Long
Dim boolSharedData As Boolean
Dim bytArrSharedData(0 To 5) As Byte
Dim strSharedData As String  '//Its good idea to store variable length data after fixed length data

Dim hFileMapTable As Long, hMap As Long

Function OpenSharedMap(Mapname As String) As Boolean
  '//Open existing file mapping
  hFileMapTable = OpenFileMapping(FILE_MAP_ALL_ACCESS, False, Mapname)
  If hMap = 0 Then
    OpenSharedMap = False
    Exit Function
  Else
    ' This says: Given the handle obtained above, give full access
    ' to the file-mapping object, starting at offset 0, and map the
    ' entire file into my process' address space.
    hMap = MapViewOfFile(hFileMapTable, FILE_MAP_WRITE, 0, 0, 0)
    If hMap = 0 Then
      MsgBox "MapViewOfFile failed - LastError: " & Hex(Err.LastDllError)
      Exit Function
    End If
    OpenSharedMap = True
  End If
End Function

Sub CreateSharedMap()
  ' INVALID_HANDLE_VALUE means: Use the Windows NT pagefile as the memory-
  ' mapped file. Otherwise, you could substitute a handle that you have created.

  ' This says: Create a file-mapping object from the pagefile,
  ' using a default security descriptor, giving Read/Write access
  ' to the committed region, with a maximum size of 4096 bytes,
  ' named szeName, and return the handle to this file-mapping
  ' object in variable 'handle'.

  '//Dont create if handle alredy opened
  If hFileMapTable <= 0 Then
    hFileMapTable = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, _
        4096, sMapName)
    If hFileMapTable = 0 Then
      MsgBox "CreateFileMapping failed - LastError: " & Hex(Err.LastDllError)
      Exit Sub
    End If
  End If

  ' This says: Given the handle obtained above, give full access
  ' to the file-mapping object, starting at offset 0, and map the
  ' entire file into my process' address space.
  If hMap <= 0 Then
    hMap = MapViewOfFile(hFileMapTable, FILE_MAP_WRITE, 0, 0, 0)
    If hMap = 0 Then
      MsgBox "MapViewOfFile failed - LastError: " & Hex(Err.LastDllError)
      Exit Sub
    End If
  End If
End Sub

Sub DeleteSharedMap()
  If hMap = 0 Then Exit Sub

  ' When we've finished with it, unmap the file-mapping object
  ' from our address space and release the handle.
  UnmapViewOfFile hMap
  CloseHandle hFileMapTable
End Sub

Sub ReadFromSharedMap()
  If hMap = 0 Then Exit Sub

  ' Now, the mapping handle can be treated just like a memory address. If holds
  ' zero them assume we're the first instance of the application, otherwise
  ' we must be the second instance and new data will be available to us.
  Dim a As Byte
  CopyMemoryRead intSharedData, hMap + offset_intSharedData, Len(intSharedData)
  CopyMemoryRead boolSharedData, hMap + offset_boolSharedData, Len(boolSharedData)
  CopyMemoryRead lngSharedData, hMap + offset_lngSharedData, Len(lngSharedData)
  CopyMemoryRead bytArrSharedData(0), hMap + offset_bytArrSharedData, Len(bytArrSharedData(0)) * (UBound(bytArrSharedData) + 1)

  Dim sLen As Long
  CopyMemoryRead sLen, hMap + offset_strSharedData, 4  '//Read string len (First 4 bytes are string len in VB)
  If sLen > 0 Then
    strSharedData = String$(sLen, 0)  '//Prepare string buffer
    CopyMemoryRead ByVal StrPtr(strSharedData), hMap + offset_strSharedData + 4, sLen * 2  '//Each character in VB string takes 2 bytes
  End If
End Sub

Sub WriteToSharedMap()
  Dim i

  If hMap = 0 Then Exit Sub

  '//Create some random data
  intSharedData = Rnd * 1000
  lngSharedData = Rnd * 100000
  boolSharedData = IIf((Rnd * 10) Mod 2 = 0, True, False)
  For i = 0 To UBound(bytArrSharedData)
    bytArrSharedData(i) = Rnd * 255
  Next

  Dim strTmp As String, sLen As Long
  strTmp = "Test string " & String$(10, Chr(65 + Rnd * 26))
  sLen = Len(strTmp)

  '//write data to shared memory
  CopyMemoryWrite hMap + offset_intSharedData, intSharedData, Len(intSharedData)
  CopyMemoryWrite hMap + offset_boolSharedData, boolSharedData, Len(boolSharedData)
  CopyMemoryWrite hMap + offset_lngSharedData, lngSharedData, Len(lngSharedData)
  CopyMemoryWrite hMap + offset_bytArrSharedData, bytArrSharedData(0), Len(bytArrSharedData(0)) * (UBound(bytArrSharedData) + 1)
  CopyMemoryWrite hMap + offset_strSharedData, sLen, 4
  CopyMemoryWrite hMap + offset_strSharedData + 4, ByVal StrPtr(strTmp), sLen * 2
  '//CopyMemoryWrite hMap, &H12345678, 4
End Sub

Sub RefreshData()
  Dim i, strArr As String
  If hMap = 0 Then Exit Sub
  Text1 = ""
  Text1 = Text1 & "Map Name  : " & " [Address: &H" & Hex(hMap) & "] " & sMapName & vbCrLf & vbCrLf
  Text1 = Text1 & "Integer  : " & " [Address: &H" & Hex(hMap + offset_intSharedData) & "] " & intSharedData & vbCrLf
  Text1 = Text1 & "Long    : " & " [Address: &H" & Hex(hMap + offset_lngSharedData) & "] " & lngSharedData & vbCrLf
  '//Note Boolean datatype is 2 bytes in VB so we need to read low byte to get True/False value
  Text1 = Text1 & "Boolean  : " & " [Address: &H" & Hex(hMap + offset_boolSharedData) & "] " & CBool(boolSharedData And &HFF) & vbCrLf

  For i = 0 To UBound(bytArrSharedData)
    strArr = strArr & bytArrSharedData(i) & " "
  Next
  Text1 = Text1 & "Byte Array : " & " [Address: &H" & Hex(hMap + offset_bytArrSharedData) & "] " & strArr & vbCrLf
  Text1 = Text1 & "String   : " & " [Address: &H" & Hex(hMap + offset_strSharedData) & "] " & strSharedData & vbCrLf
End Sub

Private Sub Command2_Click()
  Call WriteToSharedMap
End Sub

Private Sub Timer1_Timer()
  Call ReadFromSharedMap
  Call RefreshData
End Sub

Private Sub Form_Load()
  Me.Caption = Me.Caption & " Application Started at [" & Now & "]"
  '//First try to open if shared memory file already created else Create new shared map
  If OpenSharedMap(sMapName) = False Then
    Call CreateSharedMap
  End If
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  Call DeleteSharedMap
End Sub


Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.